.net 存储库与UnitOfWork

.net 存储库与UnitOfWork,.net,nhibernate,entity-framework,repository,unit-of-work,.net,Nhibernate,Entity Framework,Repository,Unit Of Work,我目前的观点是,存储库应该包含特定于实体的修改方法,如添加、删除等,而UnitOfWork应该只包含与之相关的方法,如Commit(也称为SaveChanges、SubmitChanges)和Rollback(也称为ClearChanges)。但Martin Fowler在关于UnitOfWork的文章中建议将所有修改方法添加到UnitOfWork中 那么,在EF和NHibernate的世界里,现在哪种方式更好呢 更新。 我应该注意到,即使使用我的首选方法,最终通过存储库进行的所有修改都会进入构

我目前的观点是,存储库应该包含特定于实体的修改方法,如添加、删除等,而UnitOfWork应该只包含与之相关的方法,如Commit(也称为SaveChanges、SubmitChanges)和Rollback(也称为ClearChanges)。但Martin Fowler在关于UnitOfWork的文章中建议将所有修改方法添加到UnitOfWork中

那么,在EF和NHibernate的世界里,现在哪种方式更好呢

更新。
我应该注意到,即使使用我的首选方法,最终通过存储库进行的所有修改都会进入构建到EF上下文或NHibernate会话中的UnitOfWork。我的UnitOfWork更像UnitOfWorkManager(管理内部ORM UnitOfWork)。

在NHibernate world中,UnitOfWork的主要功能由ISession实现。ISession跟踪已更改的内容,您不需要像RegisterClean或RegisterDirty这样的方法。对于更大的项目,通过使用自己的类(可以称为UnitOfWork)隐藏ISession是很有用的。例如:

public class UnitOfWork {

    private readonly ISession _session;

    public void BeginTransaction();

    public void Commit();

    public void Rollback();

    public IRepositoryFactory AllRepositories;
}
从应用程序代码中隐藏ISession的优点是,该代码不会直接引用NHibernate,从而实现更好的分层。换句话说,对于应用层来说,绕过数据访问层,直接使用NHibernateAPI将更加困难

存储库本身将包含用于添加新对象和可能删除以下对象的方法:

public interface IOrdersRepository {

    public IList<Order> FindPending();

    public void AddNew(Order order);

    public void Delete(Order order);
}
公共接口IOrdersRepository{
公共IList FindPending();
公共无效新增(订单);
公共无效删除(订单);
}

这是两种不同的模式

存储库负责从上层抽象数据存储,而工作单元负责业务事务管理。存储库允许您在不更改代码的情况下替换存储—您可以使用文本文件、XML、数据库—无论什么。UoW使您有机会控制和跟踪对实体的更改,并一次保存一个业务事务的所有更改

默认情况下,EF和NH都支持UoW,所以您不需要自己重新实现它。不过,您还是希望编写自己的存储库模式,因为这些ORM不提供现成的模式

NH和EF之上的UoW是不必要的抽象级别,可能被视为反模式


在那篇文章中,Fowler实际上并没有建议将数据操作的责任添加到UoW中。他说的是,您可以跟踪对对象的更改,并根据需要刷新/回滚它们。

我认为NH比UoW更支持开箱即用的存储库。@Vadim您能扩展您的评论或提供链接吗?NH如何支持开箱即用的存储库?ISession充当存储库,很多时候,人们试图抽象查询而不利于应用程序。现在,对于保存/验证,这可能是一个完全不同的故事。然而,对于NHibernate,您通常只担心保存一个全新的实体(无论如何都是通过ISession完成的)以及无论如何都应该在域中处理的验证(即实体)。了解这是如何脱离主题是很有趣的。