【问题标题】:Responsibilities of Repository in DDD (EntityFramework)DDD中Repository的职责(EntityFramework)
【发布时间】:2026-01-16 20:05:01
【问题描述】:
  1. 实体 Foo 和 Bar 都是聚合根
  2. Foo 引用栏
  3. SomeService 执行以下操作 一个。调用 FooRepository.FindId() 以获取 Foo 的实例 湾。修改 Foo 实例,并对 Foo 实例引用的 Bar 实例进行一些修改 C。调用 FooRepository.Update(Foo) 以持久化对 Foo 实例所做的更改

问题: 1. 知道 Foo->Bar,FooRepository.FindId() 将如何(应该)构造 Foo 实例和它引用的 Bar 实例? (假设使用了 EntityFramework 并且据我所知 EntityFramework 会自动构建实体及其依赖项) 2. 既然 Foo 实例引用了 Bar 实例,FooRepository.Update() 是否也应该持久化对 Bar 实例所做的更改? 如果答案是否定的,假设 Entity Framework 是用于数据库访问的技术,SomeService 将如何告诉存储库(或更准确地说是 EntityFramework)忽略 Bar 的更改?

【问题讨论】:

    标签: domain-driven-design


    【解决方案1】:

    阅读Effective Aggregate Design by Vaughn Vernon 后,它让我对设计聚合有了一些了解。

    作为一项规则,我将通过其标识来引用 Bar。如果要更改其 boo 状态,我将只从 BarRepository 获取它。

    【讨论】:

      【解决方案2】:
      1. 正如 rantri 所指出的,不鼓励不同聚合之间的对象引用。最好使用身份参考。这是因为聚合需要成为一个一致性边界,如果有多个聚合在起作用,这将变得难以实施。

      2. EF 应该能够更新引用的 Bar 实体。我知道在 NHibernate 中,这被称为可达性持久性,可以启用或禁用。然而,这是有问题的,因为它使推理实体如何以及何时持久化变得更加困难。告诉某些东西忽略对 Bar 的更改的最好方法是避免直接引用 bar。很多时候,引用像 Bar 这样的东西的唯一原因是出于显示目的。在这种情况下,最好使用专用的read-model 而不是污染域对象。如果 Foo 上的行为需要 Bar 引用,那么最好让周围的应用程序服务直接向它提供 Foo 需要的数据。

      【讨论】: