【发布时间】:2014-05-22 08:04:22
【问题描述】:
(这可能是重复的,但我在阅读的其他问题中没有找到任何令人满意的答案。)
我需要一些关于如何将聚合根的子实体的删除传播到数据库层的指导。我已经/阅读了几种不同的处理方法:
将已删除的子项保留在单独的集合中。让存储库在保存时删除集合中的所有项目。
直接调用某种数据映射层或存储库。
执行存储库/UoW 可能提供/侦听的某种类型的委托/事件。
什么都不做。让工作单元或存储库将整个聚合根与“非脏”副本进行比较。
值得注意的是,我真正的聚合根实现包含多个可能被删除的子集合。
为了清楚起见,这里是一个简单的例子:
public class AggregateRoot
{
private List<ChildEntity> _children;
public IEnumerable<ChildEntity> Children
{
get
{
return _children;
}
}
public void RemoveChild(ChildEntity child)
{
_children.Remove(child);
// What to do here?
// Option 1: Keep removed children i separate collection. Let
// the repository remove them on save.
RemovedChildren.Add(child);
// Option 2: Call some kind of data mapping layer or repository directly
_childRepository.Delete(child);
// Option 3: Execute some type of delegate/event that a repository
// may provide/listen to.
_onChildRemoved(this, child);
// Option 4: Do nothing. Let the Unit of work or repository compare
// the whole aggregate root with a "non-dirty" copy.
}
}
我认为选项 1 和 2 不是很优雅。
选项 4 很好,因为我不必在聚合根中实现任何逻辑,但由于我的实际实现非常大,我必须比较很多属性和集合。
我倾向于选择选项 3。它的问题是它可能需要大量的委托/事件。也许我可以实现一个通用的委托/事件。
这一定是一个相当普遍的问题,但我看到的这方面的例子非常少。你会如何处理这个问题?
【问题讨论】:
-
如果你有一个工作单元,你可能有一个在 UoW 生命周期范围内的存储库。在存储库中记录删除(它应该在哪里)并且在提交 UoW 时,存储库可以查看其删除的项目并根据需要从底层源中删除它们。如果这类似于 EF,那么它会为您处理。
-
@AdamHouldsworth 那么您将如何通知存储库删除? (顺便说一下,我没有使用EF)
-
当您删除项目时,您可以引发领域事件,以便环境变化跟踪可以捕获它以供以后参考,或者您可以在您的领域模型本身中推广这个想法(可以删除项目并所以不可用)。
标签: c# domain-driven-design aggregateroot