.net - 如何实现DDD存储库以处理具有多个实体的查询?

标签 .net domain-driven-design

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

实体:

  • 类别(UId,名称)
  • 属性(UId,名称,AttributeValues [])
  • AttributeValue(UId,名称,ParentAttributeUId)
  • 进程(UId,名称,AttributeValues [],类别[])

  • 资料模型:
  • 每个进程可以具有多个类别(例如ProcessCategoryMap表)
  • 每个进程可以具有多个AttributeValue(例如ProcessAttributeValue表)
  • 类别,属性,attributeValues之间的关系

  • 我有一个FetchByCategoryAndAttributeValues(CategoryId,AttributeValueIds [])
    返回一个数据集:
  • 匹配CategoryId和AttributeValueIds的进程列表
  • 可用于优化搜索的AttributeValue列表。

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

    有任何想法吗 ?

    问候,

    佩德罗

    ====编辑:UTC 2011/03/30 02:52 ====

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

    @正义:

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

    我不记得Eric Evans ddd书中提到过ORM的任何内容。选择一种特定的持久性技术到底有多重要?整理好域名后,您可以随意保留其所有权。当然,我当然知道NH可以提供帮助并且是强大的工具,但它本身并不是解决方案。

    @Dominic / @Justice:

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

    首先,当我看到良好的T-SQL存储过程时,对我来说很难辩解,我不是在谈论CRUD或简单的T-SQL查询。我提到的SP运行一些TSQL CTE,使用临时表合并来自不同表的度量标准数据以计算权重,并返回目标结果:进程列表,类别列表,属性值列表。针对特定的SQL数据库/服务器(例如MSFT,Oracle等)对SP进行了优化和调整。我不认为将这些计算转移到应用程序端,然后依靠ORM可以帮助您节省执行时间以及所有工作。并转发查询。对我来说,在服务器中执行所有操作并仅带来过滤后的数据有很大的不同。我可能是错的。

    @所有:
    我已经确定了真正的问题(例如Domenic用ayende链接指出),我正在将基于数据中心方法的解决方案移植到域模型方法。让我们将其搁置一旁,SP返回的计算会影响不同的模型。由于数据在数据库中的保存方式不同,因此实体之间存在共同的计算和计算范围,问题是,在迁移到DDD实现时,如何才能最好地兼顾两种实现。以及如何保留DBA作业:)

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

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

    问候,
    佩德罗

    最佳答案

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

    之所以会出现问题,是因为这个概念-带来派生或外围相关数据的多个表与领域建模并不一致。领域建模是关于定义关系和复杂的业务逻辑,这些关系和逻辑包含了核心应用程序的基本领域知识。多个不产生基本相关对象的表意味着它可能不是域模型的一部分。

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

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

    在这种情况下,您只需创建一个DTO,即可将Process和Attribute DTO合并到一个新对象中,以便在UI中使用。

    但是还有其他可能性:

    1)有时候,您不得不问自己是否在使用正确的工具进行工作。我正在研究具有非常复杂的域模型的医疗应用程序。那就是核心应用程序-在数据采集过程中执行复杂的规则。但是,一旦获取了数据,企业就会对用它做许多不同的事情感兴趣。数据采集​​模型和分析模型都不太适合,因此,与其尝试使它们协同工作,不如让它成为更好的选择,即采用数据采集模型DDD,然后使用ETL并将数据移入数据仓库,为业务提供独立的分析应用程序,该应用程序基于查询而非OOP / DDD构建。

    2)领域建模是关于定义反映真实领域的模型,而不是关系数据技术。目的是管理复杂性并创建一个可以随着业务变化而完善和发展的模型。您不会发现有很多人在做很多DDD,甚至会假装优化是其中的一个方面。相反,您可能会尽可能地与DDD建立一致的模型。如果您以后必须对模型进行尽可能多的折衷,以使无法接受的性能达到可接受的范围。

    使用查询可以做很多事情,它们效率更高。当然,如果某人根本不了解该应用程序,那么他们可能必须找出一堆东西,并且很可能必须或多或少地了解整个应用程序,然后才能了解所有内容。 DDD,当人们对应用程序的其余部分基本一无所知时,您可以使人们成功完成某项工作,但是就性能或往返而言,您甚至没有接近最佳的东西。

    尽管试图同时兼顾两者的吸引力和逻辑性,但我还是从事诸如ETL和数据仓库之类的SQL核心工作,而我则进行DDD。我对如何在一个应用程序中成功融合两个世界有一些疑问。除了最终两全其美之外,您最终还是会得到一个没有人可以使用且性能也不佳的应用程序。如果您有一堆有效的存储过程,那肯定会有一堆业务逻辑。如果您也有具有业务逻辑的“对象”,那么最终的结果是数据库中的业务逻辑,“对象模型”中的业务逻辑原来只是(还有另一个)具有类的应用程序,但没有OOP或DDD-人们多年来一直在做的事情几乎相同,并且称之为“n层”。

    不要误会我-DDD应用程序仍应基于可靠的数据库和关系原则构建,并且性能没有错。但是,许多数据库服务器处理实际上是域活动泄漏到数据库中。这些优化数据处理的许多技术也违反了OOP和DDD的多个原则。

    如果您不愿意完全放弃所有数据库内容,并且对您来说运行良好,那么您可能根本不需要甚至不想使用DDD概念。如果要DDD,最​​好的方法是将您拥有的所有内容都视为有价值的领域知识的来源,但就实现细节而言,遗留代码已被完全废弃。 DDD并不真正适合将“无DDD”应用“移植”到。

    关于.net - 如何实现DDD存储库以处理具有多个实体的查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5477506/

    相关文章:

    grails - 域有一些共同的领域,扩展域或嵌入?

    java - DDD : Can anyone explain the diffrences between DTO, 聚合根和分离实体?

    c# - 如何使用 DOT 文件导出数据?

    c# - 如何强制 Windows 重新连接到网络驱动器

    repository - DDD 聚合根/存储库结构

    c# - 通过针对接口(interface)编程来保留数据

    domain-driven-design - 用标志交换存储库

    c# - 用一行代码填充 Enumerable.ToList

    c# - .NET 中的 LINQ to JSON

    c# - 如何使用 P/Invoke SendMessage 设置边距?