19

在閱讀大量文章後,我仍然不確定與存儲庫交互時工作單元模式的職責。工作單元與存儲庫模式之間的相互作用

庫負責加載和保存骨料根實體,所以考慮以下示例代碼:

using(IUnitOfWork uow = container.CreateUnitOfWork()) 
{ 
    Repository<ARoot> roots = container.GetRepository<ARoot>(); 
    ARoot root = root.FindByName("ARoot"); 
    root.Name = "ANewName"; 

    roots.Save(root); 
    uow.Commit(); 
} 

工作接口的單元將與下面的方法來限定:

public interface IUnitOfWork 
{ 
    void Insert(object); 
    void Update(object);   
    void Delete(object); 
    void Commit(); 
    void Rollback(); 
} 

允許比方說使用一個非常簡單的SQL Mapper來實現倉庫,所以FindByName包含一些直接返回ARoot的SQL,Save實現看起來像這樣:

public void Save(T entity) 
{ 
     IUnitOfWork uow = GetUnitOfWork(); 
     // Tell the UOW we are updating this entity 
     uow.Update(entity); 
} 

然後,Unit Of Work Commit代碼會構造所有必需的SQL以將實體映射回DB中?

問題2)

如果我添加一個聚合根到工作單位,是工作的負責persisiting根的單位,其子enitities,或者應該是倉庫的保存方法中添加改變了實體到工作單位?例如

public void Save(T entity) 
{ 
     IUnitOfWork uow = GetUnitOfWork(); 
     // Tell the UOW we are updating this entity 
     uow.Update(entity); 
     uow.Update(entity.AChildObject); 
} 

或者...... Alternativly

不工作的單位只與總根處理,並COMMITED時要求其變更集中的每個對象存儲庫保存方法,保持SQL映射代碼堅持該實體在Repository,改變第一代碼示例

using(IUnitOfWork uow = container.CreateUnitOfWork()) 
{ 
    Repository<ARoot> roots = container.GetRepository<ARoot>(); 
    ARoot root = root.FindByName("ARoot"); 
    root.Name = "ANewName"; 

    //roots.Save(root); 
    uow.Update(root); 
    // and commit 
    uow.Commit(); 
} 

謝謝,

詹姆斯

回答

3

在我們的項目中,我們使用一個Repository來像實體集合一樣工作,UnitOfWork用於跟蹤這些實體的變化,並將它們寫回到數據存儲。

如果您使用的是LinqToSql或其他一些OR映射器,那麼很可能本身會實現一個UnitOfWork模式,所以我們經常只使用我們自己的IUnitOfWork中的ORMapper實例。

我們的倉庫接口通常是這樣的..

IEnumerable<Order> FindByCustomerId(string customerId); 
    void Add(Order order); 
    void Remove(Order order); 

我們沒有任何保存方法在庫中。如果我們不需要UnitOfWork,那麼Add/Remove方法直接作用於數據存儲。

如果我們需要的UnitOfWork,那麼公共接口是一樣的東西......

void Commit(); 
void Rollback(); 

存儲庫已與的UnitOfWork內部接口,所以當我們查詢資料庫,返回的對象被跟蹤UnitOfWork進行更改。 commit方法將更改寫回數據存儲區,回滾方法只是清除它的更改。

當我們使用LinqToSql DataContext的需要更改跟蹤的照顧,在回滾我們只是實例化一個新的上下文。持久性是在根目錄及其子目錄下處理的。一個UnitOfWork實例在所有存儲庫之間共享。

當我們不使用LinqToSql時,我們實現了我們自己的UnitOfWork,也許它調用了一個web服務或其他東西,在這種情況下,我們使用EntityBase類來更改實體類自身的跟蹤。

我們有一個每個根的存儲庫,但有時一個根的孩子被用作自己的根,所以我們經常需要類似於OrderLineRepository的東西,因爲我們的系統中有用戶想要搜索的用例訂單行。

3

通常我喜歡的方式,看它做的是UOW跟蹤這是通過直接調用IRepository.Save保存更改()。

我也喜歡UOW代碼到作爲一個方面進行處理和與域的相互作用的外部。這意味着它由一些全局命令處理程序或Web服務代碼處理,作爲完成請求的一部分。換句話說,開始請求會打開一個工作單元,結束它將關閉它。這樣域可以無視UoW及其實現。

犯下的工作單位是什麼原因,然後()調用.Save所做的更改和其他變化的方法來保留。很可能,UoW是以某種方式跟蹤這些變化的。

2
  • 的UnitOfWork是您的交易 處理
  • 庫正在做 acutal工作負載/對象保存到 數據存儲

我使用類似的定義:

IUnitOfWork { Commit(); } 
IRepository { GetAll(); GetById(); Add(T item); Remove(T item); } 

我不會讓UnitOfWork創建SQL - 該邏輯將存在於您的Repository中。你使用的是什麼數據存儲?

相關問題