【问题标题】:Add multiple children entities to the root aggreate or call multiple respositories将多个子实体添加到根聚合或调用多个存储库
【发布时间】:2013-03-26 17:25:11
【问题描述】:

我有一个实体 A,它有三个子实体 X、Y 和 Z。

我还有一个通用存储库,其中一个漂浮在网络上...

在我的服务方法 AXYZ()

我做了多个存储库调用:(伪代码)

repoA.Update(objectA);
repoY.Delete(objectA.PK_Id);

foreach:
  objectX.FK_ID = objectA.PK_ID;
  repoX.Add(objectX);

foreach:
  objectY.FK_ID = objectA.PK_ID;
  repoY.Add(objectY);

foreach:
  objectZ.FK_ID = objectA.PK_ID;
  repoZ.Add(objectZ);

  _unitOfWork.Commit();

现在我问自己,做所有的 foreach 是否不够或更好?而不是在 repoXXX 上添加操作 对子集合执行添加操作?:

repoA.Update(objectA);
repoY.Delete(objectA.Id);

foreach:
  objectA.CollectionX.Add(objectX);
  objectA.CollectionY.Add(objectY);
  objectA.CollectionZ.Add(objectZ);

  _unitOfWork.Commit();

附注:

无法在内存中对 repoY 执行删除操作,因为 objects_Y 未加载到上下文中。

你怎么看?

我也用域驱动设计标记了这个问题,也许这个场景与它有关?

【问题讨论】:

    标签: c# domain-driven-design entity-framework-5 repository-pattern aggregateroot


    【解决方案1】:

    如果您实际上是从 DDD 的角度来处理这个问题,那么我担心您拥有所有子实体的存储库,而不仅仅是聚合根 A。显然,每个项目都是不同的,而 DDD 是一组通常有意义的指导方针。但是,我希望repoA 处理所有四个实体的加载和持久化,除非 X、Y 和 Z 具有作为聚合根的角色。 RepositoryA 可以处理加载和持久化来自各种来源的 XYZ 对象,前提是它们没有全部存储在一个记录中,但我不希望有单独的存储库。

    除了规范的 DDD 正确性之外,我鼓励您考虑这些关系在您的域层中是如何工作的。 foreach 方法意味着使用 setter,而添加集合意味着业务对象以一种可以用通用语言表达的方式建立关系。

    我认为你的后一种方法更“正确”,但我会稍微改变一下:

    repoA.Update(objectA);
    repoY.Delete(objectA.Id);
    
    foreach:
      objectA.addX(objectX);
      objectA.addY(objectY);
      objectA.addZ(objectZ);
    
      _unitOfWork.Commit();
    

    更改子实体的操作通常在聚合根本身上公开,因为它知道如何维护所需的不变量。

    希望这会有所帮助。但是,我不知道你的全部情况。这将有助于更多地了解AXYZ() 在做什么。

    【讨论】:

    • AXYZ() 方法没有自己的逻辑,除了它在业务事务中对存储库调用进行分组。我同意你的大多数cmets。但我看到了一个问题/担忧。当我严格遵循 DDD 方法时,我的 objectA 应该有一个 objectA.DeleteY(ObjectY)。 CollectionOfObjectY 是通过我的 GenericRepository 的 FetchById 方法获取的。然后像 addXXX 方法一样在 foreach 中调用下面的 DeleteY 方法。你怎么看?
    猜你喜欢
    • 1970-01-01
    • 2010-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-21
    • 2013-01-20
    相关资源
    最近更新 更多