2011-07-27 60 views
4

我有一個這樣的倉庫:爲通用實體框架資源庫更新方法

public class Repository<T> : IRepository<T> where T : class 
{ 
    private readonly IRepositoryContext _repositoryContext; 

    public Repository(IRepositoryContext repositoryContext) 
    { 
     _repositoryContext = repositoryContext; 
     _objectSet = repositoryContext.GetObjectSet<T>(); 
    } 

    public virtual void Update(T entity) 
    { 
     ObjectSet.AddObject(entity); 
     _repositoryContext.ObjectContext.ObjectStateManager.ChangeObjectState(entity, EntityState.Modified); 
     _repositoryContext.SaveChanges(); 
    } 
    } 

現在的實際工作爲實體的所有標量的屬性,但都與實體typeOf(T),唐的性能相關的其他實體不關心實體狀態被修改,而EF只是添加新的數據。

因此,如果您舉例如Repository<Student>.Update(),並且您只更改名稱,它會找到合適的學生並更改他的名字,但它也會更改校園,儘管您已經擁有與該學生相關的校園,它將用另一個CampusId再次創建。

請讓我看看在這種情況下更新的正確方法。

+0

歡迎來到EF-Users-擁有痛苦與更新關係及相關實體的俱樂部。你可能不會爲'Update'方法找到* generic *解決方案。這是爲什麼EF中的通用存儲庫如此無用(主要原因可能是作爲內部幫助器)。 – Slauma

+2

有[沒有正確的方法](http://stackoverflow.com/questions/3635071/update-relationships-when-saving-changes-of-ef4-poco-objects/3635326#3635326)。在這種情況下,簡單通用的方法不起作用。 –

+0

好吧,你能告訴我,那麼我不直接與實體操作的情況非通用方法。相反,我通過AutoMapper將它們映射到ViewModel類 – Agzam

回答

4

我做什麼時,我想按照通用的方法被翻譯成你的代碼是這樣的:

public class Repository<T> : IRepository<T> where T : class 
{ 
    ... 

    public virtual void Update(T entity) 
    { 
     if (context.ObjectStateManager.GetObjectStateEntry(entity).State == EntityState.Detached) 
     { 
      throw new InvalidOperationException(...); 
     } 

     _repositoryContext.SaveChanges(); 
    } 
} 

我所有的代碼,然後工作,如:

var attachedEntity = repository.Find(someId); 
// Merge all changes into attached entity here 
repository.Update(attachedEntity); 

=在通用方式>操作將大量邏輯移動到上層。如何保存大型的分離對象圖沒有更好的方法(特別是涉及多對多關係並涉及刪除關係時)。

+3

此解決方案的問題在於它只考慮更新,但插入新對象時會發生同樣的問題。如果您插入一個鏈接到數據庫中已存在的其他分離實體的對象(可能會鏈接到其他實體/子實體),則將重新創建所有這些實體。什麼樣的惡夢。這似乎是這樣一種不必要的行爲,尤其是因爲這些分離的對象都具有水合ID屬性,因此很容易檢測到它們已經在之前的調用中加載。 – Marchy