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中。你使用的是什么数据存储?

相关问题