1

我想知道遵循 DDD 的人如何通过使用 EF 和存储库模式来解决潜在的性能问题,并返回带有子节点的聚合根。

例如父母 ----- 孩子 A

甚至例如 Parent ----- Child A ------- Child A2

  1. 如果我从存储库中取回聚合根的数据并使用导航属性 EF,则会触发另一个查询,因为它正在使用延迟加载。这是一个问题,因为当我们处于循环中时,我们会遇到 100 多个查询。
  2. 如果我通过使用“包含”语句从存储库中带回聚合根的数据以及子数据,这将从存储库中带回子数据及其父数据。然后,当我使用导航属性时,不会触发任何查询,因为该数据已经在内存中。

第二种方法的问题是我们的一些子对象数据可能非常大,例如 100,000+ 条记录。显然,我不想为孩子在内存中存储 100,000 多条记录。我们决定使用分页一次选择 10 个来解决这个问题,但另一个问题是,当我们尝试对子项使用总和、总数等计算时,我们只能在内存中对我们拥有的 10 条记录执行此操作拉回来。

我知道 DDD 方法是将对象图及其所有数据都放在内存中,然后遍历对象以获取需要显示的数据。

在我们的团队中存在分歧,一些人认为我们应该将聚合根及其子对象一起拉回,而有些人认为我们应该在聚合根的存储库上使用一种方法,直接查询子数据并拉回子对象。

我只是想知道其他人如何解决与父/子一起存储在内存中的大量数据的性能问题。

4

2 回答 2

0

如果您必须处理性能,则必须使用第二种方法以及在存储库上公开的特殊方法 - 这是存储库为您提供此类方法的点,否则您可以直接使用 EF 上下文/设置。

如果您使用理论数据,则理论很好 - 一旦您拥有真实数据,您必须调整理论以在现实世界场景中工作。

您也可以查看这篇文章(博客上有以下三篇文章)。它采用第二种方式,但它假装是第一种方式。它适用于Count但也许您也可以将这个想法用于其他一些场景。

于 2012-07-10T13:42:37.450 回答
0

DDD 方式并不总是撤回所有需要的数据。我们使用一种称为双重调度的模式的技术。在这里,您可以使用所需的所有参数调用聚合根的方法(或域服务),但您也可以使用它传递“仅查询”存储库类型接口参数。这使得根或其子节点可以决定需要哪些额外数据,以及何时应该通过简单地调用这个注入接口上的方法来返回它。

这种方法遵循 DDD 原则,即聚合根不应该知道存储库实现,同时提供可测试和高性能的域代码。

于 2015-01-25T20:20:22.037 回答