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

时间:2011-03-29 18:57:46

标签: .net domain-driven-design

我很难在.net解决方案中使用DDD来实现一项要求。我会尽量减少细节:

实体:

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

数据模型:

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

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

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

如何实现存储库以及调用SP的方法,当返回多个实体时,在我看来,返回的对象是一个值对象,它似乎没有在现有的实体存储库中构建?

任何想法?

此致

佩德罗

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

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

@Justice:

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

我不记得在Eric Evans ddd书中提到任何ORM。特定持久性技术的选择如何重要?一旦你整理了域名,你可以随心所欲地坚持下去。当然我知道NH可以提供帮助并且是强大的工具,但它本身并不是解决方案。

@Dominic / @Justice:

解决方案:远离商店程序。

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

@All: 我已经确定了真正的问题(比如Domenic指出了ayende链接)我正在将基于数据中心方法的解决方案移植到域模型方法中。让我们把它放在一边,SP返回的计算会影响不同的模型。由于数据在数据库中持久存在,因此在实体之间存在通用计算和计算,问题是何时转向DDD实现是如何最好地实现这两种实现。以及如何保持DBA工作:)

您可以创建一个非常好的域模型,将数据保存在N个不同的表中,问题是当您查询数据时如何为模型带来并使DDD保持良好的状态。

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

此致 佩德罗

4 个答案:

答案 0 :(得分:4)

答案 1 :(得分:3)

您需要以某种方式抽象您的持久性代码。它属于基础架构层,而不属于域层(请参阅 DDD 第68页)。您可以手动执行此操作,编写使用DataSet s的代码,或使用像NHibernate这样的ORM。

如果您要手动完成,我建议的模式与Martin的敏捷模式,实践和C#中的原则的工资单案例研究中探讨的模式类似。第569页的图表显示了他如何打包组件。

答案 2 :(得分:1)

使用NHibernate。

让ORM 成为您的存储库。这就是它的用途。

答案 3 :(得分:0)

如果你已经在使用Entity Framework,有几种方法可以做到这一点(这个答案与Pedro重叠),每个方法都有自己的限制和优点。用例:

  1. 查询EF实体并返回DTO。
  2. 使用DBContext的Database.SqlQuery直接查询SQL。如果您的DTO属性名称与您的SQL列匹配,那么它会为您映射它们。