NHibernate是否需要使用Repository模式

23

关于这个问题,已经有几个类似的问题了,但我仍然没有找到足够的理由来决定应该走哪条路。

真正的问题是,是否合理地使用存储库模式抽象化NHibernate,或者

看起来抽象化的唯一原因是为了留下一个选项,以便在需要时用不同的ORM替换NHibernate。 但是创建存储库和抽象化查询似乎就像添加另一层,并且手动完成大量的管道工作。

一种选择是将IQueryable<T>暴露给业务层并使用LINQ,但从我的经验来看,NHibernate对LINQ的支持还没有完全实现(查询不总是按预期工作,我讨厌花时间调试框架)。

虽然在我的业务层中引用NHibernate让我感到不舒服,但它本身应该是数据访问的抽象,对吧?

你对此有何看法?


你如何只使用 Linq 将新项目添加到数据库中? - Paco
@Paco:将新项目添加到数据库非常容易抽象化,我不是在谈论这个。查询才是实际的问题,因为没有简单的方法可以通过存储库启用复杂查询,除非进行足够的编码。 - vgru
3个回答

5

好问题。几天前我也在考虑这些。

实际上,尝试使用NHibernate 3.0 alpha版(或当前的主干版本),它的新LINQ提供程序比以前的要好得多。(到目前为止,我只发现一个方法不起作用,但是如果遇到默认情况下不支持的内容,可以插入自己的机制。)我在使用当前的主干版本时没有任何问题。(迄今为止?)你可以在http://www.hornget.net/packages/ 网站上找到 "每夜构建",以及针对它的FluentNHibernate构建。如果你知道如何使用Fluent,它确实可以增加你的生产力。SO社区也帮助了我

如果您的业务层允许直接依赖于NHibernate,或者您正在编写一种较小的应用程序,而这种抽象仍然可以保持可维护性,则无需使用存储库模式。然而,如果你做得好,它可以省去你很多重复的编码。

把它抽象化的原因不仅有助于您以后用另一种ORM替换NHibernate,而且由于一个叫做关注点分离的概念而成为一个好的实践。您的业务逻辑层不应该关心或知道如何访问它所使用的数据。这使得维护应用程序或其不同层变得更容易,也使团队合作变得更容易:如果X创建了数据访问层,而Y编写了业务逻辑,则他们不必详细了解彼此的工作。

公开一个IQueryable<T>是一个非常好的主意,这正是许多存储库实现正在做的。(我也是这样做的,尽管我更喜欢在一个静态类中编写它。)当然,你还需要暴露一些方法来插入或更新实体,或者提供开始和提交事务的方法,如果你想要的话。(BeginTransaction应该只返回一个IDisposable,以避免泄漏出NHibernate接口,那就没问题了。)

我可以给你一些指导:查看SharpArchitecture或FubuMVC Contrib的实现,以获取一些有关如何正确执行的想法,这是我如何解决的


感谢您的回答。实际上,我想说的是,使用 HNibernate 直接查询数据不应该让业务层对数据库实现有显著影响,一旦您将这两个模型映射在一起。我相信这就是 ORM 概念背后的原始想法。个人而言,事实上我不想直接使用它,但是使用存储库模式(如果我不暴露 IQueryable)需要额外的编码。如果 Linq 是可靠的,那将会很好。也许我会尝试 alpha 版本:)。 - vgru
我使用当前的主干暂时没有问题(还是?)更新了我的答案。 - Venemo

1
我会毫不犹豫地说:绝对要使用仓储模式,保持抽象!

1

我个人更喜欢将NHibernate抽象成存储库模式。原因是我可能仍然有其他实现用于缓存、单元测试的模拟等。我还使用IQueryable与我的存储库,虽然我让IRepository扩展IQueryable而不是在IRepository上公开类型为IQueryable的属性。

另一个存储库要点。有些人建议不要使其通用,并在方法级别上具有类型识别(即repository.Load)。然而,这假定将有一个单一的存储库知道如何处理所有类型。我不太喜欢这种单一的庞大存储库的概念。如果你正在处理多个数据库呢?或者多个持久性机制?或者某些数据类型保持相当静态并且可以被缓存,但其他数据类型则不能。这就是为什么我喜欢每种类型都有一个单独的存储库实例。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接