我应该从DDD中的存储库返回IQueryable<T>吗?

4

最近,我在重构我的DDD项目。当我查看我的Repository层时,发现我的存储库中返回IQueryable<T>。我感到困惑,我是否应该在我的DDD项目的Repository层中返回IQueryable<T>?我通常在我的Repository设计中返回IQueryable类型。但今天我从这篇文章中发现了相反的想法。我无法理解!


仓储层应该返回什么? - doublnt
IEnumerableIReadOnlyList似乎更合适。 - guillaume31
2个回答

6
如果你返回 IQueryable,就会允许领域知识从领域层泄露到消费者层。这增加了领域对象变得贫血并且所有行为都移动到其他层的风险。
虽然看起来返回 IQueryable 很方便,你可能认为你的代码变得更简单了,但这只是一种错觉;当项目增长时,IQueryable 会将你的代码转化为一个大球形混乱,领域代码随处可见。你将无法优化你的存储库或更改一种持久性到另一种(例如从 SQL 到 NoSQL)。

@jannagy02 更准确地说,你不明白什么? - Constantin Galbenu
和这篇文章: http://www.ben-morris.com/why-the-generic-repository-is-just-a-lazy-anti-pattern/ 通用仓储库只是一种懒惰的反模式。 - Constantin Galbenu
这本书写道,它可能导致你的数据模型泄漏到你的领域层——这是正确的,但你在回答中提到的领域知识泄漏是不正确的。这篇文章与这个主题无关,它是关于“通用仓储库”的。 - dvjanm
我不同意。在这个上下文中,“领域知识泄漏”和“数据模型泄漏”是相同的。此外,在这种情况下,与通用仓储相关的相同问题也适用:您会失去对查询的控制;随着您开始依赖于特定实体属性(名称和类型),封装聚合将被破坏。 - Constantin Galbenu
显示剩余3条评论

1

你可能不应该这样做。

代码库的工作不仅是抽象出持久性细节,还要提供一个明确的查询合同,定义那些需要处理命令1的领域。

如果你觉得需要进一步过滤/转换从代码库返回的内容,那么你很可能没有捕捉到应该成为代码库合同的显式查询。

有了这样的合同,查询客户端可以表达他们的意图,并且允许更容易的优化。

现在,应用一些CQRS原则并完全绕过领域模型进行查询是相当普遍的。在这种情况下,只有需要处理命令的查询才会经过存储库。但是,您不必以任何方式使用此方法,因此如果希望,存储库也可以满足报告查询。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接