将DDD映射实体框架数据模型到领域模型

3

我理解实体数据模型应该与真正的领域模型分离,以避免基础设施问题与领域本身之间的耦合,但我想知道如果所有领域属性都没有公共设置器,我们如何从数据模型映射到领域模型,特别是如果存储库实现驻留在项目的基础设施部分中,因此我们无法使用内部属性设置器。

class DomainModel
{
    string SomeProperty {get; private set:}
}

2
通过构造函数传递参数。但是EF已经是仓储模式和工作单元,为什么还需要基于此的另一个抽象层?此外,如果您使用Code First,则不需要数据模型;只需将数据库映射到域模型即可。 - L-Four
然后使用“实体拆分”等技术。不确定您所说的复杂属性中是否包含复杂属性。 - L-Four
@L-Four 员工可以有位置,这个位置可以是一个复杂类型,包含地址名称、街道号码、邮政编码和地理信息。而且地理信息也可以是另一个复杂类型,这意味着你需要有嵌套的复杂属性。我认为实体框架不支持这种情况,这意味着你的领域模型会受到基础设施问题的限制。 - Robert
1
当然支持,通过导航属性实现。 - L-Four
@L-Four 导航属性用于 (懒加载) 从另一个表中加载相关信息。您能否将1个扁平表映射到具有复杂结构的实体,例如根类-根内的复杂类型-复杂类型内的复杂类型? - Robert
显示剩余7条评论
2个回答

2
在一个包含中间“数据模型”的架构中,Entity Framework 不再控制域实体的实例化方式。这由 Repository 控制。因此,它们不一定需要公共 setter,你也可以使用构造函数重新创建它们。
其中一种技术在这里解释:https://vaughnvernon.co/?p=879 请注意,如果你认为 EF 对实体的影响很小,则可以避免使用额外的数据模型并使用私有 setter(请参见https://lostechies.com/jimmybogard/2014/04/29/domain-modeling-with-entity-framework-scorecard/),以获得更简单的替代方案。

0
我理解实体数据模型应该与真正的领域模型分离。

不正确

避免基础设施问题和领域本身之间的耦合。

正确


可以使用EF直接持久化你的领域模型,但是你不应该将你的领域模型与EF耦合。

这是什么样子?

假设你有一个名为Domain的项目,其中包含你的模型,还有另一个名为DataStore的项目,其中包含你的存储库以持久化这些模型(使用EF)

通常情况下,使用EF时,你会在要持久化的模型上使用属性和各种无用的东西,但这会污染并将这些模型与EF作为存储机制耦合起来,并从你的纯粹的Domain项目中添加对EF的依赖 - 这就是我们要避免的。

EF6来拯救,看看EF6 FluentApi,你可以配置你的领域模型与EF一起工作,而不需要向Domain项目添加任何EF特定的属性或依赖项。

主键?

modelBuilder.Entity<OfficeAssignment>().HasKey(t => t.InstructorID);

索引?

modelBuilder 
.Entity<Department>() 
.Property(t => t.Name) 
.HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute()));

如果你为每个对象都这样做,那么很快就会变得痛苦。但是,如果你遵循一些约定(或使用基本类型使其更容易),

那么你可以使用反射来自动地为域中的所有实体执行此操作。

祝你好运!


4
我有点晚了,但是在 fluent api 中如何解决外键问题,当你不想让导航属性污染你的领域模型时? - Robert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接