如何实现 DDD 存储库来处理具有多个实体的查询?

2023-12-30

我正在努力在 .net 解决方案中使用 DDD 来实现需求。我会尽量减少细节:

实体:

  • 类别(UId、名称)
  • 属性(UId、名称、属性值[])
  • 属性值(UId、名称、ParentAttributeUId)
  • 进程(UId、名称、属性值[]、类别[])

数据模型:

  • 每个进程可以有多个类别(例如 ProcessCategoryMap 表)
  • 每个进程可以有多个 AttributeValues(例如 ProcessAttributeValue 表)
  • 类别、属性、属性值之间没有关系

我有一个 s.p. FetchByCategoryAndAttributeValues(CategoryId, AttributeValueIds []) 返回一个数据集:

  • 与 CategoryId 和 AttributeValueIds 匹配的进程列表
  • 可用于细化搜索的 AttributeValues 列表。

如何实现存储库加上调用SP的方法,当返回多个实体时,在我看来,返回的对象是一个值对象,并且似乎不适合现有的实体存储库?

有任何想法吗 ?

Regards,

Pedro

==== 编辑:2011/03/30 下午 02:52 世界标准时间 ====

我正在更新我的问题,以重视所有评论并帮助面临类似挑战的其他人。

@正义:

解决方案:使用 ORM,例如NHibernate 以及使用 ORM 的所有理由

我不记得 Eric Evans 的 ddd 书中提到过 ORM。选择特定的持久性技术有何重要意义?一旦您整理好域名,您就可以按照您希望的方式自由保留它。当然,我知道 NH 可以提供帮助并且是一个强大的工具,但它本身并不是一个解决方案。

@多米尼克/@正义:

解决方案:远离存储过程。

首先,对我来说,当我看到好的 T-SQL 存储过程时,很难证明其合理性,我不是在谈论 CRUD 或简单的 T-SQL 查询。我提到的 SP 运行一些 TSQL CTE,结合来自不同表的指标数据来计算权重,使用临时表并返回客观结果:进程列表、类别列表、属性值列表。 SP针对特定的SQL数据库/服务器进行了优化和调整,可以是MSFT、Oracle等。我不相信将这些计算转移到应用程序端,然后依赖于ORM将有助于缩短执行时间并转发查询。对我来说,在服务器中完成所有这些操作和仅引入过滤后的数据有很大的不同。我可能是错的。

@全部: 我已经确定了真正的问题(就像 Domenic 通过 ayende 链接指出的那样),我正在将基于数据中心方法的解决方案移植到域模型方法。让我们把这个放在一边,SP 返回的计算会影响不同的模型。由于数据在数据库中的持久化方式,存在常见的计算,并且计算在实体之间受到限制,因此问题是在转向 DDD 实现时如何充分利用这两种实现。以及如何保住 DBA 的工作:)

您可以创建一个非常好的领域模型,将数据持久化到 N 个不同的表中,问题是当您查询该数据时如何将其引入模型并保持 DDD 良好的状态。

谢谢大家,我仍在寻找想法、答案等:)

问候, 佩德罗


您面临的直接问题是如何引入包含一些数据和一些“不相关”数据的数据集,这些数据允许以与域模型一致的方式进一步过滤该数据。

这是一个问题的原因是因为这个概念——引入派生或外围相关数据的多个表与域建模并不真正一致。领域建模是关于定义包含核心应用程序的基本领域知识的关系和复杂的业务逻辑。不产生根本相关对象的多个表意味着它可能不是域模型的一部分。

如果您没有本质上适合您尝试执行的操作的对象,则意味着您的模型不完整,或者在这种情况下,您可能正在尝试将应用程序的用户界面方面泄漏到域模型中。大概是后者。

解决方案还包括用户界面视图架构,如 MVP 或 MVC。域对象是关于跨事务执行业务规则 - 保存和更新。例如,使用 DTO 和 Presenter 来组装任何类型的“新”或“混合”对象,这些对象不代表核心领域知识,而是被构造为以用户想要的某种方式向用户呈现数据。

在这种情况下,您只需创建一个 DTO,将流程和属性 DTO 合并到一个新对象中以供 UI 中使用。

但还有其他一些可能性:

1) 有时您必须问自己是否使用了正确的工具来完成这项工作。我正在开发一个具有非常复杂的领域模型的医疗应用程序。这就是核心应用程序 - 在数据采集过程中执行复杂的规则。但是,一旦获取了这些数据,企业就会有兴趣用它来做许多不同的事情。获取模型和分析模型根本不适合,所以我认为更好的选择是使用 DDD 获取模型,然后使用 ETL 并将数据移动到数据仓库中,而不是尝试让它们一起工作为企业提供一个基于查询而不是 OOP/DDD 构建的独立分析应用程序。

2)领域建模是关于定义反映真实领域的模型,而不是关系数据技术。目标是管理复杂性并创建一个可以随着业务变化而完善和发展的模型。您不会发现很多人做了很多 DDD,甚至假装优化是其中的一个方面。相反,您构建的模型应尽可能与 DDD 一致。如果以后必须这样做,您只需尽可能地妥协该模型,以便将不可接受的性能纳入可接受的范围。

您可以使用查询做很多很多事情,而且效率要高得多。当然,如果有人根本不了解该应用程序,他们可能必须追踪一堆内容,并且很可能必须或多或少地了解整个应用程序,然后才能理解所有内容。 DDD 可以让人们在对应用程序的其余部分基本一无所知的情况下成功地完成某些工作,但在性能或往返方面却没有任何接近最佳的东西。

尽管它似乎试图两全其美,但它既有吸引力又合乎逻辑,我做硬核 SQL 的东西,比如 ETL 和数据仓库,我也做 DDD。我对如何成功地将这两个世界合并到一个应用程序中有些怀疑。您最终得到的应用程序可能没有人可以使用,而且性能也不佳,而不是两全其美。如果你有一堆高效的存储过程,那么里面必然有一堆业务逻辑。如果您还有具有业务逻辑的“对象”,那么您最终得到的是数据库中的业务逻辑、“对象模型”中的业务逻辑,结果只是(又一个)具有类的应用程序,但不是OOP 或 DDD - 与人们多年来一直在做的事情几乎相同,并将其称为“n 层”。

不要误会我的意思 - DDD 应用程序仍然应该构建在可靠的数据库和关系原则上,并且性能没有任何问题。但许多数据库服务器处理实际上是泄漏到数据库的域活动。此外,许多优化数据处理技术都违反了 OOP 和 DDD 的多项原则。

如果您不愿意完全放弃所有数据库内容,并且它对您来说效果很好,那么您可能不需要甚至不想首先转向 DDD 概念。如果您想要 DDD,最​​好的方法是将您拥有的一切视为有价值的领域知识的来源,但就实现细节而言,遗留代码已被完全放弃。 DDD 并不真正适合“移植”非 DDD 应用程序。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何实现 DDD 存储库来处理具有多个实体的查询? 的相关文章

  • 将 ASP.NET Intranet 应用程序与 Outlook 日历集成的技术

    我不能再忽视用户的叫喊声了 他们想要一个任务调度系统 而在某些时候我必须交付 我正在考虑制作自己的系统 并不难 但是用户将拥有两个并行的任务管理系统 因为他们已经使用 Outlook 来完成相同的事情 在 Outlook 日历 任务集成方面
  • VB.NET 与 C# 中的属性实现多级继承

    假设我有 2 个接口 如下定义 public interface ISkuItem public string SKU get set public interface ICartItem ISkuItem public int Quant
  • 如何使 PLINQ 在 .NET 4.0 beta 2 中产生更多并发线程?

    在以前版本的并行扩展中 您可以设置线程数 enumerable AsParallel numberOfThreads 但现在这种超载不再可用 现在该怎么做呢 在新版本中 您可以使用扩展方法 WithDegreeOfParallelism i
  • Spring.Net可以起到PostSharp的作用吗?

    几个月前 我发现了 PostSharp 有一段时间 它非常棒 但随后法律部门回复说他们不喜欢旧版本的许可证 然后部门告诉我2 0的价格高得令人无法接受 对于我们需要的座位数量 我非常失望 但并不沮丧 我想 这不可能是唯一的这样的框架 我一直
  • 使用反应式扩展对事件进行单元测试

    我在用着 NET 的反应式扩展 Rx http msdn microsoft com en us devlabs ee794896 aspx将事件公开为IObservable
  • 在wince上用c#静默运行命令行程序

    我再次需要一些帮助 我使用 net Compact Framework 和编程语言 C 来为运行 WinCE 5 0 的移动设备进行开发 我想要完成的是以编程方式安装网络驱动器 为此 应用程序在后台线程中运行以下代码 ProcessStar
  • 批准后使用 jenkinsfile 构建促销

    仅当更改管理使用 servicenow 更改票证或通过手动批准批准它时 我才需要使用 jenkins 文件将我的构建升级到生产 我想要类似的东西 产品构建只有在经理批准后才能手动触发 他 她应该收到带有批准 拒绝链接的批准邮件 或者 如果与
  • Selenium - 异常 - 连接关闭

    我正在使用最新的 Selenium WebDriver 使用 NET Microsoft 技术堆栈运行 这些天我观察到的是 套件中的所有测试都开始失败并抛出此异常 附加信息 向远程 WebDriver 服务器发送 HTTP 请求以获取 UR
  • 双击定时器事件

    我正在开发一个应用程序 将用户的眼球运动与光标运动映射起来 从而开发一个免提光标控制系统 我正在使用 Open CV 库的 NET Wrapper for C 即 Emgu CV 进行开发 我被困在想要打开文件 文件夹的地方 这样当光标放在
  • 工具提示出现在表单/窗口后面! (C#/VS 2008)

    由于某些奇怪的原因 我在 VS 2008 C winforms 应用程序中的工具提示显示在表单后面 这非常令人沮丧 我不知道我应该做什么 有人遇到过这个吗 有想法吗 PS 我正在表单中以编程方式执行 toolstip show 您可能需要检
  • 如何将具有固定模式的值数组反序列化为强类型数据类?

    我在找出一种干净的 尽可能 方法来以特定格式反序列化某些 JSON 数据时遇到了一些麻烦 我想将数据反序列化为强类型数据对象类 对于具体细节非常灵活 以下是数据的示例 timestamp 1473730993 total players 9
  • 在DDD中,值对象的实际优势是什么?

    到目前为止 我知道实体对象有 ID 而值对象没有 但在最常见的示例中 人员实体附加了地址值对象 创建单独的地址对象而不是仅将地址属性保留在 Person 实体中的最大优点是什么 除了已经提到的事情之外 格雷格 杨 http weblogs
  • 从字符串数组中删除项目

    我有一个包含如下数据的数据库字段 76 60 12 例如 如果我想删除60 我该怎么办 要删除的号码可以是任何地方 如果需要的话 我还需要删除逗号 我正在使用 NET 2 0 我会用逗号分割字符串 删除元素 然后再次连接字符串 希望这一切都
  • 有没有办法根据值是大于 0.5 还是小于 0.5 来进行下限/上限?

    我正在尝试舍入我的价值观 以便如果它是0 5或更大 则变为1 否则就变成0 例如 3 7 gt 4 1 3 gt 1 2 5 gt 3 有任何想法吗 Math Round 3 7 MidpointRounding AwayFromZero
  • 如何检查DLL文件是否已注册?

    如何以编程方式查找用 C 编写的 DLL 文件是否已注册 我已经尝试过这段代码 但它没有成功 如果我注册一个 DLL 文件并使用此代码进行检查 它将返回 如果我取消注册它并运行同一段代码 它会再次返回 true 我将 DLL 文件的完整路径
  • 拆分容器,制作固定面板

    我有一个水平方向的 splitcontainer 我希望仅在表单调整大小期间为 panel2 设置固定高度 并让 splitter 调整 panel2 大小 现在我正在这样做 但我不满意 因为用户注意到面板调整了大小 Private Sub
  • .NET ListView列顺序问题

    我在表单中遇到问题 我已按以下顺序将列添加到 NET ListView 控件 A B C D A D 列的显示索引按顺序为 0 3 但它们的显示顺序错误 A B D C these are switched at runtime 注意 一切
  • 锁定文件的一个块

    我有一个大小为 192k 的文件 我想锁定文件的中间部分 例如 我想用 c 锁定文件的 64k 128k 知道如何锁定文件的那部分吗 你需要使用锁定文件Ex http msdn microsoft com en us library win
  • 如何将 Binding.Path 属性绑定到基础数据?

    我正在尝试以非常动态的方式绑定 TextBlock 的 Text 属性 我需要从底层对象获取路径 这是数据模板
  • 为什么 32 位 .NET 进程的引用类型的最小大小为 12 字节

    我正在读专业 Net 性能 https rads stackoverflow com amzn click com 1430244585本书有关参考类型内部结构的部分 它提到 对于 32 位 net 进程 引用类型具有 4 字节的对象头和

随机推荐