gpt4 book ai didi

c# - 使用 ORM 的丰富域模型

转载 作者:太空狗 更新时间:2023-10-29 18:20:41 25 4
gpt4 key购买 nike

我似乎遗漏了一些东西,大量使用谷歌并没有帮助提高我的理解......
这是我的问题:
我喜欢以一种持久性无知的方式创建我的领域模型,例如:

  1. 如果不需要的话,我不想添加 virtual
  2. 我不喜欢添加默认构造函数,因为我希望我的对象始终是完整构造的。此外,在依赖注入(inject)的上下文中,对默认构造函数的需求是有问题的。
  3. 我不想使用过于复杂的映射,因为我的域模型使用了 ORM 不易支持的接口(interface)或其他构造。

对此的一种解决方案是拥有单独的领域对象和数据实体。使用存储库模式并从 ORM 返回的数据实体构建域对象,可以轻松解决构造域对象的检索问题。使用 AutoMapper,这将是微不足道的,并且代码开销不会太多。

但我对这种方法有一个很大的问题:如果不自己编写代码,我似乎无法真正支持延迟加载。此外,对于同一个“事物”,我会有很多类,尤其是在 WCF 和 UI 的扩展上下文中:

  1. 数据实体(映射到 ORM)
  2. 领域模型
  3. WCFDTO
  4. 查看模型

所以,我的问题是:我错过了什么?这个问题一般是怎么解决的?

更新:
到目前为止的答案表明我已经担心的事情:看起来我有两个选择:

  1. 在域模型上做出妥协以匹配 ORM 的先决条件,从而拥有 ORM 泄漏到的域模型
  2. 编写大量额外代码

更新:
除了已接受的答案外,请参阅 my answer有关我如何为我解决这些问题的具体信息。

最佳答案

我会质疑匹配 ORM 的先决条件是否一定是“做出妥协”。但是,从高度 SOLID、松散耦合的架构的角度来看,其中一些观点是合理的。

ORM 框架的存在只有一个原因;采用您实现的域模型,并将其持久化到类似的数据库结构中,而无需实现大量容易出错、几乎不可能进行单元测试的 SQL 字符串或存储过程。他们还可以轻松实现延迟加载等概念;在需要对象之前的最后一分钟补水,而不是自己构建一个大对象图。

如果您想要存储过程,或者拥有它们并且需要使用它们(无论您是否愿意),大多数 ORM 都不是完成这项工作的正确工具。如果你有一个非常复杂的域结构,以至于 ORM 无法映射字段与其数据源之间的关系,我会严重质疑你为什么要使用那个域和那个数据源。如果你想要 100% 的 POCO 对象,而不了解背后的持久性机制,那么你可能最终会绕过 ORM 的大部分功能,因为如果域没有虚拟成员或子集合可以用代理替换,然后你被迫急切加载整个对象图(如果你有一个巨大的相互链接的对象图,这很可能是不可能的)。

虽然 ORM 确实需要在域设计方面的持久性机制领域的一些知识,但 ORM 仍然会产生更多 SOLID 设计,IMO。如果没有 ORM,这些是您的选择:

  • 滚动您自己的存储库,该存储库包含一种方法,用于在您的域中生成和保留每种类型的“顶级”对象(“上帝对象”反模式)
  • 创建各自处理不同对象类型的 DAO。这些类型要求您对 ADO DataReader 和您的对象之间的获取和设置进行硬编码;在一般情况下,映射会大大简化流程。 DAO 也必须相互了解;要持久化发票,您需要发票的 DAO,它还需要发票行、客户和 GeneralLedger 对象的 DAO。而且,所有这些都必须内置一个通用的、抽象的事务控制机制。
  • 设置对象持久化的 ActiveRecord 模式(并将更多关于持久性机制的知识融入您的领域)

总的来说,第二个选项是最可靠的,但通常它会变成一个三分之二的野兽来维护,尤其是在处理包含反向引用和循环引用的域时。例如,为了快速检索和/或遍历,InvoiceLineDetail 记录(可能包含装运单或税务信息)可能直接引用 Invoice 及其所属的 InvoiceLine。这创建了一个 3 节点循环引用,它需要一个 O(n^2) 算法来检测对象是否已经被处理,或者硬编码逻辑涉及反向引用的“级联”行为。我以前不得不实现“图表步行者”;相信我,如果有任何其他方法可以完成这项工作,您肯定不想这样做。

因此,总而言之,我的观点是,对于足够复杂的领域,ORM 是所有弊端中最少的。它们封装了关于持久性机制的大部分非 SOLID 内容,并将关于其持久性的域知识简化为非常高级的实现细节,这些细节分解为简单的规则(“所有域对象必须将其所有公共(public)成员标记为虚拟”)。

关于c# - 使用 ORM 的丰富域模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7690725/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com