实体框架中的聚合根支持

Bri*_*Low 13 domain-driven-design entity-framework aggregateroot

我们如何告诉实体框架有关聚合的信息

  1. 保存聚合时,保存聚合中的实体
  2. 删除聚合时,删除聚合中的实体
  3. 当两个不同的用户尝试修改同一个aggreate中的两个不同实体时,会引发并发错误
  4. 加载聚合时,即使在我们访问聚合中的所有实体之前有一些时间延迟,也要提供聚合的一致时间点视图

(实体框架4.3.1代码优先)

Lad*_*nka 7

EF提供的功能允许您定义聚合并使用它们:

  1. 这是最痛苦的部分.EF与实体图一起使用.如果您有像Invoice这样的实体,并且此实体具有相关InvoiceLine实体的集合,您可以像聚合一样处理它.如果您处于附加方案中,一切都按预期工作,但在分离方案中(聚合不由EF加载或由不同的上下文实例加载)您必须将聚合附加到上下文实例并告诉它您确切改变了什么=设置状态对象图中的每个实体和独立关联.
  2. 这是通过级联删除处理的 - 如果您加载了相关实体,EF将删除它们,但如果不加载,则必须在数据库中的关系上配置级联删除.
  3. 这由数据库中的并发令牌处理 - 最常见的是时间戳或行转换列.
  4. 您必须使用预先加载并在开头加载所有数据(=一致的观点),否则您将使用延迟加载,在这种情况下,您将没有一致的观点,因为延迟加载将加载关系的当前状态但它将不会更新您已加载的聚合的其他部分(如果您尝试使用EF实现此类刷新,我会将其视为性能杀手).


bre*_*ick 6

我专门为此编写了GraphDiff.它允许您通过提供流畅的映射来定义更新时的"聚合边界".我已经在需要来回传递分离的实体图的情况下使用它.

例如:

// Update method of repository
public void Update(Order order)
{
    context.UpdateGraph(order, map => map
        .OwnedCollection(p => p.OrderItems);
}
Run Code Online (Sandbox Code Playgroud)

以上将告诉实体框架更新订单实体并合并OrderItems的集合.以这种方式进行映射允许我们确保实体框架仅在我们在聚合上定义的边界内管理图形并忽略所有其他属性.它支持所有实体的乐观并发检查.它处理更复杂的场景,并且还可以在许多场景中处理更新引用(通过AssociatedCollections).

希望这可以使用.