将多个子实体添加到根聚合或调用多个存储库

时间:2013-03-26 17:25:12

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

我有一个实体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.Add操作不是在repoXXX而是 对子集合执行添加操作?:

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

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

  _unitOfWork.Commit();

旁注:

repoY上的Delete操作无法在内存中完成,因为objects_Y未加载到上下文中。

您怎么看?

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

1 个答案:

答案 0 :(得分:0)

如果你实际上是从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()正在做什么。