23

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

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

似乎抽象它背后的唯一原因是让自己可以选择在需要时用不同的 ORM 替换 NHibernate。但是创建存储库和抽象查询似乎又增加了一层,而且大部分工作都是手工完成的。

一种选择是使用暴露IQueryable<T>到业务层并使用 LINQ,但根据我的经验,在 NHibernate 中仍然没有完全实现 LINQ 支持(查询并不总是按预期工作,我讨厌花时间调试框架)。

虽然在我的业务层中引用 NHibernate 会伤到我的眼睛,但它本身应该是对数据访问的抽象,对吧?

您对此有何看法?

4

3 回答 3

5

好问题。前几天我也在想他们。

实际上,试试 NHibernate 3.0 alpha(或当前的主干),它的新 LINQ 提供程序比以前的提供程序要大得多。(到目前为止,我只发现了一种不起作用的方法,但是如果您遇到默认情况下不支持的东西,可以使用您自己的机制。)使用当前的主干我没有问题(还没有?) . 您可以在http://www.hornget.net/packages/站点上找到“夜间”构建,以及针对它的 FluentNHibernate 构建。如果您知道如何使用 Fluent,它确实会提高您的工作效率。SO 社区也确实帮助了我

如果您对直接依赖于 NHibernate 的业务层感到满意,或者您正在编写一个较小的应用程序,该应用程序在没有这种抽象的情况下仍可维护,那么您最好不要使用存储库模式。但是,如果你做得对,它可以为你节省大量的冗余编码。

抽象它的原因不仅是因为您可以稍后用另一个 ORM 替换 NHibernate,而且由于一个名为Separation of Concerns的概念,这是一个很好的实践。您的业​​务逻辑层不应该关心或知道如何访问它所使用的数据。这使得维护应用程序或其不同层更容易,这也使团队合作更容易:如果 X 创建数据访问层,Y 编写业务逻辑,他们不必详细了解彼此的工作。

公开 anIQueryable<T>是一个非常好的主意,这正是许多存储库实现现在正在做的事情。(我也是,虽然我更喜欢在静态类中编写它。)当然,如果您愿意,您必须公开一些插入或更新实体的方法,或者用于开始和提交事务的方法。(BeginTransaction 应该只返回一个IDisposable以避免泄漏 NHibernate 接口,这样就可以了。)

我可以给你一些指导:查看 SharpArchitecture 或 FubuMVC Contrib 的实现,以获得一些关于如何正确操作的想法,这就是我解决它的方法。

于 2010-05-01T19:10:48.873 回答
1

我只想说一个很大的YES!有一个存储库模式,保持抽象!

于 2010-05-01T19:16:45.343 回答
1

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

另一个存储库点。有些人建议不要使其通用并在方法级别(即repository.Load)进行类型标识。但是,这假设将有一个知道如何处理所有类型的存储库。我不是一个单一的单体存储库这个概念的忠实粉丝。如果您要处理多个数据库怎么办?还是多种持久性机制?或者某些数据类型保持相当静态并且可以缓存,但其他数据类型不能。这就是为什么我喜欢每种类型都有一个单独的存储库实例。

于 2010-08-10T16:11:45.260 回答