ENTITY FRAMEWORK CORE入门:四、DbSet.Attach(实体)与DbContext.Entry(实体).State = EntityState.Modified 区别

当你使用这个DbSet.Update方法时,实体框架将你实体的所有属性标记为EntityState.Modified,所以跟踪它们。如果你只想更改部分属性,而不是全部属性,请使用DbSet.Attach

首先看一下我们province表中的数据。

方式一,使用Attach更新某个属性的值(注意,不是所有的属性都作修改)

紧接着上一节的内容,我们在HomeController中添加修改代码,看下DbSet.Attach(实体)所做的修改。

//四、DbSet.Attach(实体)与DbContext.Entry(实体).State = EntityState.Modified 区别
           
 //DbSet.Attach(实体)
            var proAttach = _context.Provinces.Where(p => p.Name == "上海").FirstOrDefault();
            if (proAttach != null)
            {
                proAttach.Population = 10;
                _context.Provinces.Attach(proAttach);
            }
            _context.SaveChanges();
            

我们看一下局部变量是啥,更新语句是什么,只有Population属性被修改。

Entity Framework Core 中,实现泛型仓储模式可以提供一个统一的数据访问层接口,从而简化对数据库的通用操作。以下是一个完整的实现示例,包括接口定义和具体实现。 ### 泛型仓储接口定义 ```csharp public interface IRepository<T> where T : class { Task<IEnumerable<T>> GetAllAsync(); Task<T> GetByIdAsync(int id); Task AddAsync(T entity); Task UpdateAsync(T entity); Task DeleteAsync(int id); } ``` ### 泛型仓储实现 ```csharp public class Repository<T> : IRepository<T> where T : class { private readonly DbContext _context; private readonly DbSet<T> _dbSet; public Repository(DbContext context) { _context = context; _dbSet = _context.Set<T>(); } public async Task<IEnumerable<T>> GetAllAsync() { return await _dbSet.ToListAsync(); } public async Task<T> GetByIdAsync(int id) { return await _dbSet.FindAsync(id); } public async Task AddAsync(T entity) { await _dbSet.AddAsync(entity); await _context.SaveChangesAsync(); } public async Task UpdateAsync(T entity) { _dbSet.Attach(entity); _context.Entry(entity).State = EntityState.Modified; await _context.SaveChangesAsync(); } public async Task DeleteAsync(int id) { var entity = await GetByIdAsync(id); if (entity != null) { _dbSet.Remove(entity); await _context.SaveChangesAsync(); } } } ``` ### 使用示例 在 ASP.NET Core 应用程序中,可以通过依赖注入将 `DbContext` 注册到服务容器中,并通过构造函数注入到仓储类中。 #### 注册服务 在 `Startup.cs` 文件中注册 `DbContext` 和仓储服务: ```csharp public void ConfigureServices(IServiceCollection services) { services.AddDbContext<MyDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); services.AddScoped(typeof(IRepository<>), typeof(Repository<>)); services.AddControllers(); } ``` #### 控制器使用仓储 在控制器中注入 `IRepository<T>` 并使用它来执行数据库操作: ```csharp [ApiController] [Route("[controller]")] public class BlogsController : ControllerBase { private readonly IRepository<Blog> _blogRepository; public BlogsController(IRepository<Blog> blogRepository) { _blogRepository = blogRepository; } [HttpGet] public async Task<IActionResult> GetAllBlogs() { var blogs = await _blogRepository.GetAllAsync(); return Ok(blogs); } [HttpGet("{id}")] public async Task<IActionResult> GetBlog(int id) { var blog = await _blogRepository.GetByIdAsync(id); if (blog == null) { return NotFound(); } return Ok(blog); } [HttpPost] public async Task<IActionResult> CreateBlog(Blog blog) { await _blogRepository.AddAsync(blog); return CreatedAtAction(nameof(GetBlog), new { id = blog.Id }, blog); } [HttpPut] public async Task<IActionResult> UpdateBlog(Blog blog) { await _blogRepository.UpdateAsync(blog); return NoContent(); } [HttpDelete("{id}")] public async Task<IActionResult> DeleteBlog(int id) { await _blogRepository.DeleteAsync(id); return NoContent(); } } ``` ### 总结 通过上述代码,可以实现一个基于 Entity Framework Core 的泛型仓储模式,从而提供统一的数据访问接口[^1]。这种模式不仅提高了代码的可维护性和可测试性,还可以简化数据访问逻辑的实现。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值