【问题标题】:MVC DDD EF Complex Child Object TraversalMVC DDD EF 复杂子对象遍历
【发布时间】:2012-05-14 14:24:44
【问题描述】:

我正在就聚合根和使用导航属性遍历子对象进行辩论。

场景 1:

  • 客户是聚合根
  • 地址是一个实体
  • 联系人是一个实体

一个客户可以有多个地址,一个地址可以有多个联系人。我使用客户 ID 查询下面的客户存储库并返回一个客户对象。

Dim customer as Customer = _customerRepository.GetById(request.Id)

如果我们需要访问客户地址,我们将遍历客户对象中的地址,如下所示。

Dim address as Address = customer.RetrieveAddress(request.AddressId)

然后将针对 x 个子对象执行此方法。我展示的示例很简单,但就包含数百万条记录的数据库表而言,一旦查询并返回聚合根对象,其他人在遍历多个子对象时如何处理性能问题?

场景 2:

与上面的示例相同,但我们不是查询客户存储库并返回客户对象,而是返回一个子对象。

Dim address as Address = _customerRepository.GetAddressById(request.AddressId)

现在,因为我们已经查询了地址对象,这意味着我不必遍历客户对象来获取它。即使我已经使用客户存储库直接查询地址表并返回地址对象,在遵循 DDD 时是否允许这样做?或者我应该使用方案 1 来查询客户存储库并返回作为聚合根的客户对象并遍历子对象?

我问的原因是因为在我们的数据库图中,我们有几个表要从我们的聚合根遍历,并且随着时间的推移它可能包含数百万条记录,这会降低性能。

只是想知道其他人如何在不降低性能的情况下彻底应用 DDD,因为在使用带有导航属性的 EF 时,一旦您使用它们,它就会为每个子对象发送一个查询,如果它在其中,则可能发送 100 多个查询一个 for 循环。

迈克

【问题讨论】:

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


    【解决方案1】:

    聚合是一项棘手的业务,决定聚合边界需要大量思考。阅读您的问题,我不太确定您是根据行为而不是数据库实体关系设计聚合。正如 Eben 所说,后一种方法不会走得太远,而且您的聚合最终可能会非常大(就子实体的数量而言)。

    我读过的关于该主题的最有见地的内容之一是Effective Aggregate Design by Vaughn Vernon。我肯定会推荐给它一个阅读。他谈到的一件重要的事情是试图使你的聚合尽可能小。这自然会对性能有所帮助。

    对于子 entities,我不会做你在场景 2 中所做的事情,因为你不应该通过聚合根来改变实体的状态;这保持了不变量。话虽如此,您的示例使用的地址对象可能是 值对象,因此出于性能原因使用单独的地址存储就可以了。

    在开始使用 DDD 时,我认为重要的是要提醒您在设计选择上仍然需要务实; DDD 并不能为您解决所有问题。在大多数情况下,设计选择是对性能等因素的权衡。

    【讨论】:

      【解决方案2】:

      您将无法使用 ER 图来确定聚合:)

      所有权不一定推断聚合。您只是指关系遍历。聚合根是一项棘手的业务。我在我的网站http://www.ebenroux.co.za 上写了一些关于这个的博客,你可能想特别看看这个:

      Natural vs. Synthetic Aggregates

      聚合具有不同的边界,需要特定的领域知识来确定该边界的位置。之后就是简单地成为所有权或弱引用。

      【讨论】:

        猜你喜欢
        • 2022-01-04
        • 2023-01-05
        • 2017-10-16
        • 1970-01-01
        • 1970-01-01
        • 2015-09-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多