2

我试图将 NHibernate 与我的服务层分离时碰壁了。我的架构如下所示:

网络 -> 服务 -> 存储库 -> nhibernate -> 数据库

我希望能够从我的服务层和可能的 web 层产生休眠查询,而这些层不知道它们正在处理什么 orm。目前,我的所有存储库都有一个 find 方法,该方法包含IList<object[]> criteria. new object() {"Username", usernameVariable};这允许我从我的架构中的任何地方传递一个标准列表。NHibernate 接受它并创建一个新的 Criteria 对象并添加传入的标准。这适用于我的服务层的基本搜索,但我希望能够传入我的存储库转换为 NHibernate 标准的查询对象。

真的,我很想实现类似这个问题中描述的东西:抽象休眠标准是否有价值。我只是没有找到任何关于如何实现这样的东西的好资源。该问题中描述的方法是一个好方法吗?如果是这样,任何人都可以提供一些关于如何实施这种解决方案的指示吗?

4

2 回答 2

9

抽象出 ORM 将:

  • 带来很多重新定义它的API的工作
  • 无法优化/批量数据库访问
  • 使理解执行的查询变得更加困难
  • 将导致大量的 SELECT N+1

一切都是为了很少的价值:交换 ORM 框架的模糊选项很可能会有很多其他问题

  • 缺少特征
  • 实现上的细微差别
  • 学习曲线

更新:经验

我曾经参与实现现有 DAL 抽象的新提供者。它最终表现不佳,引入了很多错误,错误处理一团糟,有时使用过时的数据,因为应用程序采用默认实现。原因:

  • 缓存不知道上下文
  • 缓存实现有不同的语义
  • 批处理 API 差异太大而无法抽象
  • 错误是特定于实现的(例如FileNotFound -> FilesearchDialog对于基于 tcp/ip 的数据库是无用的)
  • 错误恢复是不同的(每个实现都有自己的一组可以从中恢复的错误)
  • 锁定机制不同
  • SQL 数据库中没有一致的更改事件
  • 嵌套事务
  • 模型类中的默认实现流血
  • 重新实现所有抽象的 Queryies 需要做很多工作,并且引入了很多复制粘贴错误
  • 在不明确说明顺序的情况下进行查询将在不同的实现中返回不同的排序结果

对应用程序进行了大量重构:

  • 去除只有一种实现提供的功能
  • 每个实现的缓存管理
  • 由于瞬态数据导致的包装器身份问题
  • 非常困难地对两个数据存储进行查询

附加点:

  • 通过抽象 DAL 迁移数据非常缓慢
  • 由于上述问题,实现另一个实现永远不会发生它太昂贵(在提到的场景中,我们开始慢慢地重新实现整个项目)
  • 实现 DAL API 的正确语义极其困难,因为在纯 API 中没有使用上下文

(业务任务的)移植在 IMO 中的痛苦会少得多,因为我们在一些情况下这样做是因为性能。

更新 2:经验 2:尝试从 NHibernate 移植到 EntityFramework 时遇到障碍(使用 NH 实现但不能在合理时间内使用 EF 4)

  • 嵌套事务
  • 枚举支持
  • 使用compositeId 的引用(如何摆脱referenceIds)
  • 组件中的引用
  • 读取批处理(Futures),方便页面+计数
  • 映射 CultureInfo(IUserType 支持)
于 2012-10-16T10:57:55.170 回答
0

感谢您的回复!我明白你在说什么,但这些答案并不能解决我的问题。由于我正在编写的系统状态,我无法更改我的架构。相反,我只是将我的所有 sql/hql/criteria api 查询保留在存储库层内,而不是尝试向我的服务公开某种复杂的查询类。这种方法应该可以正常工作。不过,对于我的下一个架构方法,我将考虑其他答案中提出的观点。

于 2012-10-16T14:09:16.233 回答