使用实体框架代码最有效地处理创建、更新、删除

Posted

技术标签:

【中文标题】使用实体框架代码最有效地处理创建、更新、删除【英文标题】:Most efficiently handling Create, Update, Delete with Entity Framework Code First 【发布时间】:2012-09-26 09:17:00 【问题描述】:

注意:我使用的是实体框架版本 5

在我的通用存储库中,我有 AddEditDelete 方法如下:

public class EntityRepository<T> : IEntityRepository<T>
    where T : class, IEntity, new() 

    readonly DbContext _entitiesContext;

    public EntityRepository(DbContext entitiesContext) 

        if (entitiesContext == null) 

            throw new ArgumentNullException("entitiesContext");
        

        _entitiesContext = entitiesContext;
    

    //...

    public virtual void Add(T entity) 

        DbEntityEntry dbEntityEntry = _entitiesContext.Entry<T>(entity);
        if (dbEntityEntry.State != EntityState.Detached) 

            dbEntityEntry.State = EntityState.Added;
        
        else 

            _entitiesContext.Set<T>().Add(entity);
        
    

    public virtual void Edit(T entity) 

        DbEntityEntry dbEntityEntry = _entitiesContext.Entry<T>(entity);
        if (dbEntityEntry.State == EntityState.Detached) 

            _entitiesContext.Set<T>().Attach(entity);
        

        dbEntityEntry.State = EntityState.Modified;
    

    public virtual void Delete(T entity) 

        DbEntityEntry dbEntityEntry = _entitiesContext.Entry<T>(entity);
        if (dbEntityEntry.State != EntityState.Detached) 

            dbEntityEntry.State = EntityState.Deleted;
        
        else 

            DbSet dbSet = _entitiesContext.Set<T>();
            dbSet.Attach(entity);
            dbSet.Remove(entity);
        
    

您认为这些方法是否实施得很好?尤其是Add 方法。如下实现Add方法会更好吗?

public virtual void Add(T entity) 

    DbEntityEntry dbEntityEntry = _entitiesContext.Entry<T>(entity);
    if (dbEntityEntry.State == EntityState.Detached) 

        _entitiesContext.Set<T>().Attach(entity);
    

    dbEntityEntry.State = EntityState.Added;

【问题讨论】:

@CoffeeAddict 这是 EF 5.0.0。数据库优先或代码优先,我猜这里没关系,因为它是通用存储库代码。 您可以使用新发布的库,该库将自动设置实体图中所有实体的状态。你可以阅读my answer to the similar question。 【参考方案1】:

添加:

public bool Add<E>(E entity) where E : class
        
            DataContext.Entry(entity).State = System.Data.EntityState.Added;
            Save();
        

更新:

 public bool Update<E>(E entity) where E : class
        
            DataContext.Entry(entity).State = System.Data.EntityState.Modified;
            Save();
        

删除:

 public bool Delete<E>(E entity) where E : class
        
            DataContext.Entry(entity).State = System.Data.EntityState.Deleted;
            Save();
        

还有一个私有的 Save() 方法,它返回 true 或 false,因此您可以根据结果在控制器中轻松回退

private bool Save()
        
            return DataContext.SaveChanges() > 0;                
        

这只是我的通用存储库的一部分。它在企业应用程序中表现出色。

更新:

分离只影响传递给方法的特定对象。如果 被分离的对象在对象上下文中有相关的对象,那些 对象未分离。

在设置实体状态或调用SaveChanges() 时,EF 会自动在图中附加分离的对象。

我真的不知道为什么需要从上下文中分离对象。您还可以使用AsNoTracking() 从数据库中加载实体,而无需首先将它们附加到上下文中。

【讨论】:

如果您传递给AddEdit 方法的对象处于Detached 状态会发生什么? 这是否可以代替 DbContext 或存储库中的 IDbSet&lt;T&gt; 属性? 这太完美了。谢谢! where E : class 的目的是什么 - 不知道谷歌可以找到更多关于它的信息? @Cody 这是一个约束,所以类型参数必须是引用类型msdn.microsoft.com/en-us/library/d5x73970.aspx

以上是关于使用实体框架代码最有效地处理创建、更新、删除的主要内容,如果未能解决你的问题,请参考以下文章

ORM 或其他东西可以有效地处理带有 order 列的 SQL 表

如果存在则更新行否则使用实体框架插入逻辑[关闭]

最有效的实体框架代码第一方法展平/投影具有特定子实体的父实体

实体框架 6:在上下文中禁用跟踪时更新实体

如何首先使用实体​​框架代码更新一行?

使用在多个列上具有主键的实体框架更新数据库