28

注:我使用實體框架版本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; 
} 
+0

這是使用Code First嗎? – PositiveGuy

+1

@CoffeeAddict它是EF 5.0.0。數據庫優先或代碼優先,在這裏沒關係,因爲它是一個通用的存儲庫代碼。 – tugberk

+0

您可以使用新發布的庫,它將自動設置實體圖***中所有實體的狀態。你可以閱讀[我對類似問題的回答](http://stackoverflow.com/questions/5557829/update-row-if-it-exists-else-insert-logic-with-entity-framework/39609020#39609020) 。 –

回答

37

對於添加:

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(); 
     } 

所以你可以根據結果

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

這在控制器後備容易返回true或false私人Save()方法只是我的普通倉庫的一部分。它在企業應用程序中非常適用。

UPDATE:

拆離僅影響傳遞給該方法的特定目的。如果分離的對象 在對象上下文中具有相關對象,則這些對象不會分離。

當設置實體的狀態或調用SaveChanges()時,EF會自動在圖中附加分離的對象。

我真的不知道爲什麼你需要從上下文中分離對象。您也可以使用AsNoTracking()從數據庫加載實體,而不必將它們附加到上下文中。

+0

如果傳入「添加」或「編輯」方法的對象處於「分離」狀態,會發生什麼情況? – tugberk

+0

看我的答案更新。 –

+0

感謝您的回答。 – tugberk