DDD存储库EF性能

时间:2012-07-10 12:58:54

标签: asp.net-mvc entity-framework repository domain-driven-design

我想知道关注DDD的人如何通过使用EF和存储库模式来回避带有子项的聚合根来解决潜在的性能问题。

e.g。亲        -----孩子A

甚至例如亲                -----孩子A.                        -------儿童A2

  1. 如果我从存储库中恢复聚合根数据并使用导航属性EF,则会触发另一个查询,因为它正在进行延迟加载。这是一个问题,因为当我们处于循环中时,我们遇到了100多个查询。
  2. 如果我使用子项的数据从存储库中带回聚合根的数据,并使用“包含”语句,这将使存储库中的子数据与其父项一起返回。然后,当我使用导航属性时,不会触发任何查询,因为该数据已经在内存中。
  3. 第二种方法的问题是我们的子对象的一些数据可能非常大,例如100,000多条记录。 显然,我不想在孩子的记忆中存储100,000多条记录。我们决定使用分页来一次选择10来解决这个问题,但另一个问题是当我们尝试对子项进行计算时,如总和,总计数等,但我们只能在内存中对我们的10条记录进行拉回来了。

    我知道DDD方法是将对象图形中的所有数据拉回到内存中,然后遍历对象以获取需要显示的数据。

    我们团队中存在分歧,有些人认为我们应该将聚合根和它们的孩子拉回来,并且有些人认为我们应该在聚合根的存储库上有一个方法来直接查询子数据并拉回子对象。

    我只是想知道其他人如何通过父/子将大量数据存储在内存中来解决性能问题。

2 个答案:

答案 0 :(得分:0)

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

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

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

答案 1 :(得分:0)

DDD方式并不总是拉回所需的所有数据。一种技术我们使用称为双调度的模式。这是您打电话给聚合根源的地方。方法(或域名服务)包含它需要的所有参数,但同时也只传递了一个'查询'存储库类型接口参数也是。这使得root或其子代可以决定需要多少额外数据,以及何时应该通过简单地调用此注入接口上的方法来返回它。

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