带或不带存储库的 NHibernate

Posted

技术标签:

【中文标题】带或不带存储库的 NHibernate【英文标题】:NHibernate with or without Repository 【发布时间】:2010-05-01 14:24:39 【问题描述】:

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

真正的问题是,abstract the NHibernate using a Repository pattern 或 not 是否合理?

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

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

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

您对此有何看法?

【问题讨论】:

如何仅使用 linq 将新项目添加到数据库中? @Paco:向数据库添加新项目很容易抽象,我不是在谈论这个。查询是真正的问题,因为没有简单的方法可以在没有足够编码的情况下通过存储库启用复杂的查询。 【参考方案1】:

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

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

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

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

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

我可以给你一些指导:查看 SharpArchitecture 或 FubuMVC Contrib 的实现,以了解如何正确执行此操作,这里是 how I solved it。

【讨论】:

感谢您的回答。实际上,我想说的是,一旦将这两个模型映射在一起,使用 HNibernate 直接查询数据不应该将数据库实现显着暴露给业务层。我相信这是 ORM 概念背后的原始想法。就个人而言,事实是我不想直接使用它,但是存储库模式(如果我不公开 IQueryable)需要额外的编码。使用 Linq 会很可爱,如果它可靠的话。也许我会尝试 alpha 版本:)。 我在使用当前主干方面没有任何问题(还没有?)。更新了我的答案。【参考方案2】:

我只想说“是”!有一个存储库模式,保持抽象!

【讨论】:

【参考方案3】:

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

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

【讨论】:

以上是关于带或不带存储库的 NHibernate的主要内容,如果未能解决你的问题,请参考以下文章

定义带或不带导出的变量

使用带或不带括号的 python 装饰器

-XX:MaxPermSize 带或不带 -XX:PermSize

使用参考值作为参数,带或不带“ref”? [复制]

为啥定义带或不带引号的 JavaScript 对象字面量会有所不同? [复制]

WordPress最近的新闻/帖子,带或不带特色图片