聚合根和实体框架

Posted

技术标签:

【中文标题】聚合根和实体框架【英文标题】:Aggregate root and Entity Framework 【发布时间】:2014-02-17 10:54:01 【问题描述】:

我正在为使用实体框架代码优先的聚合根的纯实现而苦苦挣扎。假设我们有一个标准的 Order 和 OrderItem 问题,后者是前者的孩子。我们需要在 Order 类中有一个 OrderItem 项的只读集合,这样我们就可以(通过设计)在它的聚合根(即 Order 类)中控制 OrderItems 的添加、删除或更新。

    我们如何实现这个 OrderItem(s) 列表?这个列表需要是只读的,这样其他开发者就不会尝试在列表中手动添加 OrderItem(s),避免使用应该使用的方法。

    我们如何在 EF Code First 中映射该集合?私有属性不可映射。

【问题讨论】:

可以映射私有成员:***.com/a/13810766/861716 确实如此,但这几乎不是 DDD 解决方案。您在域类和底层持久性机制之间添加耦合。 硬道理是属于实体框架上下文的类模型是data layer in the first place。一切都必须优化以方便数据访问(虚拟成员、用于标识和外键的 Id 属性、双向关系、与数据库表非常相似的类)。我的观点是:你不能用 EF 类模型做 DDD,ORM 会以这样或那样的方式占用很大的空间。 @GertArnold 是的,看起来是这样。我同意你的看法。 【参考方案1】:
    我们如何实现这个 OrderItem(s) 列表?这个列表需要是只读的,这样其他开发者就不会尝试在列表中手动添加 OrderItem(s),避免使用应该使用的方法。

只读列表不会阻止其他开发人员向其中添加和删除项目。它只会阻止他们更改 OrderItems 的引用指针。

您可以做的是将列表设为私有,并在 Order 上有一个 AddItem、RemoveItem 和 UpdateItem 方法以及用于迭代目的的列表的 IEnumerable getter。

    我们如何在 EF Code First 中映射该集合?私有属性不可映射。

我从未使用过 EF,但由于之前做过一些 DDD,因此为您的应用程序和逻辑、真正的域模型和另一组实体为您的数据访问框架提供一组实体很有用,在此案例 EF。并使用 AutoMapper 之类的东西从您的 EF 实体映射到您的域实体。

您不必总是有两组实体,但对于像这样有问题的实体,制作 EF 想要的实体,然后添加从对象到对象的额外映射步骤。

【讨论】:

以上是关于聚合根和实体框架的主要内容,如果未能解决你的问题,请参考以下文章

实体框架空间聚合函数

使用实体框架从聚合根中删除子记录

领域驱动设计中实体和聚合之间的区别

值对象如何存储在数据库中?

Rafy 领域实体框架简介

领域驱动设计、.NET 和实体框架