我看到的东西,如随后的代码实现的工作模式的单元:

    private HashSet<object> _newEntities = new HashSet<object>();
    private HashSet<object> _updatedEntities = new HashSet<object>();
    private HashSet<object> _deletedEntities = new HashSet<object>();

和然后有用于添加实体到每个这些HashSets的方法。

在提交的UnitOfWork为每个实体创建一些映射器实例,并调用插入,更新,删除从一些虚映射方法。

这种方法对我的问题是:插入,更新的名称,删除方法是硬编码的,所以它看起来如此的UnitOfWork能够只做一些简单的CRUD操作。但如果我需要以下用法:

UnitOfWork ouw = new UnitOfWork();
uow.Start();

ARepository arep = new ARepository();
BRepository brep = new BRepository(); 

arep.DoSomeNonSimpleUpdateHere();
brep.DoSomeNonSimpleDeleteHere();

uow.Commit();

由于我然后我可以注册A和B只有插入,更新实体,删除操作,但我现在需要的自定义操作现在三HashSet的方法失败。

这样看来,我不能的总是的堆栈的库操作,然后用UnitOfWork.Commit();

执行所有这些

如何解决这个问题?第一个想法是 - I可以存储方法的地址

arep.DoSomeNonSimpleUpdateHere();
brep.DoSomeNonSimpleDeleteHere(); 

在UOW实例并执行它们uow.Commit()但然后我也来存储所有的方法的参数。这听起来很复杂。

在其他的想法是让库完全UOW感知:在DoSomeNonSimpleUpdateHere我可以检测到有一个UOW运行,所以不执行Commit但保存一些堆栈操作参数和“待定”状态存储库实例(很明显,我不能保存在UOW一切,因为UOW不应该依赖于具体的实现库)。然后我注册在UOW实例所涉及的资源库。当UOW调用Commit(),它会打开一个事务,并呼吁像同花顺一些事情()为每个挂起库。现在库的每一个方法需要一些工具和UOW检测和操作推迟购买<=>

所以短期的问题是 - 什么是注册在多个存储库中UOW然后<=>所有未决的改变最简单的方法他们都在一个单一的交易

有帮助吗?

解决方案

这似乎甚至复杂的更新可以被分解成一系列的修改向一个或多个DomainObjects的。调用DoSomeNonSimpleUpdateHere()可以修改多个不同DomainObjects,这将触发对每个对象对应调用UnitOfWork.registerDirty(domainObject的)。在以下示例代码,我已经替换码的呼叫到该DoSomeNonSimpleUpdateHere从系统中删除不活动的用户。

UnitOfWork uow = GetSession().GetUnitOfWork();
uow.Start();

UserRepository repository = new UserRespository();
UserList users = repository.GetAllUsers();

foreach (User user in users)
{
  if (!user.IsActive())
    users.Remove( user );
}

uow.Commit();

如果您担心不得不遍历所有的用户,这里是使用对象的标准来限制用户数的另一种方法从数据库中抽取。

UnitOfWork uow = GetSession().GetUnitOfWork();
uow.Start();

Repository repository = new UserRespository();
Criteria inactiveUsersCriteria = new Criteria();
inactiveUsersCriteria.equal( User.ACTIVATED, 0 );
UserList inactiveUsers = repository.GetMatching( inactiveUsersCriteria );
inactiveUsers.RemoveAll();

uow.Commit();

在UserList.Remove和UserList.RemoveAll方法将通知每个用户删除的的UnitOfWork。当UnitOfWork.Commit()被调用时,它会删除其_deletedEntities发现每个用户。这种方法可以让你无需编写SQL查询每个特殊情况下创建任意复杂的代码。使用批量更新将在这里很有用,因为的UnitOfWork将不得不执行多个DELETE语句对所有不活动的用户只有一个语句代替。

其他提示

这是你有这个问题的事实表明,不使用Repository模式本身,而是更多的东西一样多表数据网关。一般情况下,储存库是用于加载和保存的总根源。因此,当您保存一个实体,你的持久层保存在聚合根实体实例的对象图的所有更改。

如果,在你的代码,你必须每表(或实体)大约一个“仓库”,你很可能实际使用一个表数据网关或数据传输对象。在这种情况下,可能需要有传递到活动事务的参考的每个Save()方法的装置(或工作单元)。

在埃文斯DDD的书,他建议让交易控制到资源库的客户端,我会同意,这不是一个很好的做法,尽管它可能是难以避免,如果你实际使用的表格数据网关模式。

我终于找到这一个:

http://www.goeleven.com/Blog/82

笔者解决了使用三个列出更新/插入/删除的问题,但他不存储实体存在。相反,库代表和他们的参数存储。因此,对提交笔者呼吁每个注册的委托。通过这种方法,我可以登记甚至一些复杂的资料库等方法避免使用单独的TableDataGateway。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top