采用Nhibernate + Repository模式的建议方法是什么?
有很多不同的文章和意见,我不知道该采取什么方式。例如Take this lengthy article。它给出了Query对象的示例,但每个具体的存储库在其构造函数中接受ISession
。在BL(业务层)中,我应该关心NH会话?
创建一堆存储库,每个存储库都有一堆特定的方法?
显然,这是太多的工作,因为BL现在“被允许”意识到NHibernate(Repository is the new Singleton)?
创建一个通用存储库,但公开IQueriable<T>
并在BL中使用LINQ
偶尔有一个LINQ-to-NHibernate无法处理的查询(或者我需要在一百个查询中手动调整一次SQL)。使用自定义repo方法很容易,但依赖于LINQ的代码几乎不可能。仅仅因为LINQ在某些情况下被破坏而使用两者都是无稽之谈。
查询对象?
QueryOver
也是特定于NH的,这意味着BL再次意识到DAL的实现。
又一种方法?
显然,我需要能够管理某处的交易,可能使用工作单元模式(尽管周围也有许多不同的实现)。
答案 0 :(得分:13)
软件架构领域存在许多相互矛盾的观点,其中很多都是非常有根据的。
1)是的,为每个聚合根定义存储库可能有点过分,但您可能会发现检索该根数据的方式可能是特定于它的,并且您希望能够在自定义存储库中控制它。 Ayende的文章非常有说服力,并且密切关注典型开发人员“过度架构”解决方案的愿望 - 通常会损害功能。
2)使用LINQ和NHibernate是一个选项,但我要强调的是,如果你这样做,你必须让自己能够回退使用条件查询或HQL。在那个阶段,你可能会发现自己投入了很多例外,你会想知道抽象的初始点是什么。
3)QueryOver
是一个围绕条件查询的类型安全包装器,仅此一点就使它们对我更具吸引力。我经常发现自己会回到他们提供的纯粹控制的标准 - 后备往往是我必须使用“魔术弦”。这基本上使NHibernate成为您的数据访问抽象。实际上,大多数“存储库”都是一个更好的抽象,因为它们中的大多数只是提供CRUD方法......存储库应该能够处理查询规范(确切地说QueryOver
如何工作)。
就交易而言 - 这取决于您的框架。实际上,我不认为在应用程序中使用工作单元模式是否现实或有益,并隐藏它的实现(你可以抽象它 - 但重点是什么? - 你真的要改变你的ORM吗?) / p>
如果你正在使用ASP.NET,那么只需(至少)在请求开始时启动事务,回滚异常并在结束时提交。
如果您使用的是WinForms,那么您可能需要将每个UI任务的生命周期视为您的工作单元。
答案 1 :(得分:2)
该网站现在似乎已经停止了,但我真的很喜欢Bob Craven的做法,并将其用于一些大型项目:
http://blog.bobcravens.com/2010/06/the-repository-pattern-with-linq-to-fluent-nhibernate-and-mysql/ 编辑:Google cache version of the link
他使用泛型和UOW模式进行数据访问。
是的,当你需要依赖SQL时会有轻微的痛苦,但是我使用了一个可以抽象的数据服务层。即数据服务层尽可能使用通用dao(90%的时间),并在其他地方使用vanilla SQL /其他框架。