我有一个带有聚合根的域模型:
public interface IAggregateRoot {
public string Id { get; }
public string Foo { get; set; }
public int Bar { get; set; }
public IList<IChildEntity> Children { get; }
}
Children集合往往变得非常大,当通过IAggregateRootRepository检索到IAggregateRoot实例时,我将延迟加载它。我的问题是这个;如果我想将IChildEntity添加到IAggregateRoot的Children集合中,我的存储库如何允许我避免持久化整个聚合?
例如,假设我的IAggregateRootRepository看起来如下所示:
public interface IAggregateRootRepository {
public IAggregateRoot GetById(string id);
public void AddOrUpdate(IAggregateRoot root);
}
然后,我可以通过IAggregateRootRepository.GetById()获取IAggregateRoot实例,将子项添加到Children集合,然后通过IAggregateRootRepository.AddOrUpdate()将其全部保存,从而添加到Children集合。然而,每当我添加一个子实体时,这将持续整个聚合根以及其大量的子集。如果我的存储库看起来像:
,我想我可以解决这个问题public interface IAggregateRootRepository {
public IAggregateRoot GetById(string id);
public void AddOrUpdate(IAggregateRoot root);
public void AddOrUpdate(IChildEntity child);
}
但是,正如我已经理解了存储库模式,存储库应该只处理聚合根,上面的解决方案肯定会打破这个要求。
还有其他更好的方法来避免这个问题吗?
答案 0 :(得分:5)
聚合根应该围绕写边界设计 - 也就是说,通常在单个批处理/事务中写入数据库的任何东西。如果您发现需要单独持久保存非根的子实体,则可能需要重新考虑您的设计,并使您的子实体成为一个独特的聚合根本身(因为它有一个单独的写边界)。
您的原始聚合根将不包含子实体,而是引用它们(因为它们现在是聚合根本身 - 聚合根之间的链接应该通过引用键)。这也有助于你的延迟加载策略。
希望有所帮助:)
答案 1 :(得分:-1)
通常,ORM负责数据库中整个聚合的更新。它检测在检索到的实体中所做的更改,并且仅保留聚合的已修改实体。
因此,如果您只将子项添加到根目录,并且您在聚合中没有其他修改。然后ORM只会为子实体插入一条新记录,并留下根聚合和其他子记录。