0

我正在開發一個MVC應用程序。我有一個領域模型,我使用數據訪問和實體框架代碼優先的存儲模式。我還有一個UnitOfWork類,我稱之爲存儲庫操作。如何實現聚合根存儲庫添加與EF的子實體

我的問題主要出現在我嘗試利用聚合根並通過其父存儲庫處理子對象時。

這就是問題: 父類「供應商」有幾個與部門的合同。在這種情況下,我選擇將合同作爲供應商的子女。

要添加新的合同,我需要添加一個方法來在我SupplierRepository添加一個合同,我想:

public class SupplierRepository : GenericRepository<Supplier> 
     { 

      public SupplierRepository(MyContext context) 
      : base(context) 
      { 
      } 

      public void AddSupplierContract(SupplierContract contract) 
      { 
       var supplier = context.Suppliers.Find(contract.SupplierId); 
       supplier.Contract.Add(contract); 

      } 

而且我也試過:

  public void AddSupplierContract(SupplierContract contract) 
      { 
       context.Entry(contract).State = EntityState.Added; 
      } 

     } 

當我打電話

_unitOfWork.save(); 

我得到一個錯誤告訴我:

一個實體對象不能被IEntityChangeTracker的多個實例引用

的UnitOfWork instansiates我的DbContext(myDbContext)和我SupplierRepository並調用myDbContext.Save()

  1. 我爲什麼會這樣行爲
  2. 我應該怎樣實現一個聚合根庫(CRUD操作的子對象)

據我瞭解,我應該在倉庫中有一個方法來接受合同並添加它,而不是在我的MVC應用程序的控制器中執行此操作,但我似乎無法使其工作。

我見過很多關於Aggregate Roots的信息,但沒有看到如何實現它的例子。

謝謝。

解決方案:

嗯,我終於想通了。

所以這是不與存儲庫中的問題,但新的SupplierContract queryed用於創建它的用戶實體店鋪(通過擴展方法)。很明顯,這個上下文沒有處理,因此當我爲了保存合同實體而進行實例化時,我有兩個當前的DbContext。

希望有人通過閱讀這節省了時間。

的聚合根庫由我只是在做這樣的SupplierRepository解決:

public void AddSupplierContract(SupplierContract contract) 
    { 
     db.SupplierContracts.Add(contract); 
    } 

,並呼籲UnitOfWork.Save()方法。

回答

1

雖然在技術上可能已經解決了這個問題,我希望大家都知道有一些根本性的缺陷,在您的設計(除非你使用福勒庫):倉庫( DDD類)只處理總量。 SupplierContract需要添加到上下文的事實並不是調用代碼的關注點。那麼,爲什麼要揭露這種方法?我也會重新考慮讓存儲庫委託保存(爲什麼還有一個UoW)。就聚合物而言,我覺得你似乎將它們視爲結構對象,而不是行爲的對象。因此,你似乎處於一個痛苦的世界,經歷了一些動作,但沒有獲得任何價值。

+0

那麼,揭露它的唯一原因是我需要將合同信息(折扣,交付費等)保存到數據庫,以便控制器從表單中獲取輸入並通過調用_unitOfWork.SupplierRepository.AddSupplierContract(contractToAdd )。儘管你可能對結構思想是正確的,但我仍然認爲供應商是提供合同的供應商,因此也是根源。我不知道我會怎麼做呢? – cfs 2012-02-13 23:53:45

+0

aSupplier.AddContract(contractToAdd)供應商彙總將其添加到內部集合中的情況。當爲供應商調用保存時,它應該按照可達性添加合同。對於另一種方法,看這裏:http://stackoverflow.com/questions/8556365/ef-4-2-code-first-and-ddd-design-concerns/8560328#8560328 – 2012-02-14 09:39:38

+1

嗯,我想這似乎是一個更好的解決方案,並給供應商一些行爲。然後由供應商庫管理的聚合根將只持續供應商的狀態。所以我然後獲取當前供應商(mySupplier),調用mySupplier.AddContract(contractToAdd),然後我調用_unitOfWork.SupplierRepository.Update(mySupplier)並保存?聽起來像更好的解決方案... – cfs 2012-02-14 11:19:54

0

要擺脫該錯誤,您應該使用相同的MyContext實例來創建所有存儲庫。如果您使用某個依賴注入器,它應該允許您通過單個請求配置相同的MyContext對象。例如,對於Ninject,這將是

kernel.Bind<MyContext>().ToSelf().InRequestScope(); 
+0

這實際上是UnitOfWork背後的ide,它們使用相同的上下文。不知何故,通過試圖在它的父庫中添加一個子項,它似乎創建了一個新的上下文......也就是說,我的存儲庫從我的UnitOfWork類獲取上下文,所以它只會創建一個上下文,並保留它直到它被丟棄(UnitOfWork實現IDisposable)。 – cfs 2012-02-13 16:49:08