域驱动设计和实体框架中的实体应该相同吗?

问题描述:

我已经第一次开始使用Entity Framework Code First,并且对我们的greenfield应用程序围绕域而不是围绕关系数据库表(这是我多年以来的工作方式)构建的方式印象深刻。域驱动设计和实体框架中的实体应该相同吗?

因此,我们正在C#中构建实体,每次我们进行新的迁移时都会反映在数据库中。

我的问题是:这些相同的实体(即设计时是否考虑了实体框架)与域驱动设计中的实体(即表示域的核心)具有相同的作用?

对象关系映射和域驱动设计是两个正交的问题。

ORM

的ORM就是在这里居住桥梁数据库中的关系数据模型和对象模型,任何对象模型之间的差距。

由EF定义的实体具体表示任何对象您希望将关系模型的某些子部分映射到(和来自)。事实证明,英孚的创造者想通过给实体命名来赋予这些实体以商业内涵,但最终没有任何东西会以这种方式强制你。您可以将其映射到“查看模型”以查看它的所有内容。

DDD

从DDD的角度来看,有没有这样的事情“实体设计的EF记”。 DDD实体应该是持久性无知的,并且不会有任何ORM的痕迹。领域层无论在何时何地存储对象,都没有兴趣。

当两人见面

,其中两个正交的概念是交叉的唯一一点在你的ORM映射针对的对象模型恰恰是你的域模型。通过将EFD映射文件指向非域图层中的DDD实体,并避免使用EF工件(如数据注释),可以用EF称为“代码优先”(但实际上应该命名为常规ORM)直接在你的实体类中。这在使用Database First时不可行,因为交易的DDD“纯度”部分不能满足。

总之,这些术语相互冲突,但它们应该在概念上被认为是两个不同的东西。一个是域对象本身,另一个是可以指示相同代码的指针,但它可能指向其他任何东西。

+1

但是,当您使用代码时,首先会添加几个框架引用。例如,使用System.ComponentModel.DataAnnotations.Schema 。它如何承受任何ORM的痕迹?你能解释一下吗? – mnhmilu 2017-07-20 06:17:50

+1

@mnhmilu System.ComponentModel.DataAnnotations.Schema不是实体框架的一部分。它可以在域图层中使用,但不必在实体类中引用它。 – guillaume31 2017-07-25 14:06:57

+0

@ guillaume31那么域对象和实体是不同的类,应该保存在不同的包中(例如com.xyz.domain.Person和com.xyz.entities.Person)? – 2017-07-26 08:54:00

我会说,他们可以是相同的

有时候不需要支持两个模型。当您遵循代码优先的方法时,您的实体为您的域建模,您的基础架构(ORM)分离域和持久层。

可能是合理的维护两个模型如果你有遗留数据库,并必须维护它。

还有另外两个SO问题,这会有所帮助:

Well.That是我use.And的方法我已经看到了很多别人做现在,我正在使用洋葱体系结构/模式来创建我的应用程序,并使得一切都依赖于域实体使我的生活变得更加轻松。因为每当我想改变例如处理我的数据库的层时,我都可以在没有cha唠叨用户界面层(ASP.NET MVC应用程序,WPF应用程序...等)...我建议做同样的事情。

让我们等待其他职位

我什么MikeSW表示同意(第3个答案)。当你设计你的域实体,你应该做的,而无需关心谁将会消耗这些实体(奥姆斯或任何其他技术服务不管出于什么目的),有一个想法。设计他们,他们将是可重复使用的,他们不会需要在未来(希望)

他们不应是一样的,他们正在设计改变不同的目的是。 ORM实体是一个或多个表的外观,其目的是模拟关系表上的OOP。域实体是关于定义域概念的。如果你的域实体只是一个数据结构,那么你可以重用它作为一个EF实体,但这只是一种情况。

DDD应用程序永远不会知道EF或ORM。它只知道一个存储库。因此,你的域对象(DO)不知道EF。您可以选择将它们视为EF实体,作为实现细节,但是......只有在您的DOs已定义并实施其用例后,您才应该这样做。您应尽可能延迟持久性的实现(使用内存中的repos(列表)来进行开发)。

当你达到这一点时,你会知道如果你可以重用你的DO为ORM的目的,或者如果你需要其他方式(如纪念品)。

请注意,由域驱动的DO设计,应考虑持久性问题,但不应受其影响,即不根据数据库架构设计DO。每个DO的持久性策略可能不同,它可能涉及或不涉及ORM。

如果您正在使用事件采购进行DO,则ORM不存在。序列化对象相同。它很重要如何一个对象将被应用程序使用(更新和查询),这就是为什么我说你应该推迟持久性实现。对于很多DO,你不需要rdbms(即使你正在使用它),所以ORM实体看起来更像是一个KeyValuePair(Id =>序列化数据)。

总而言之,它们对于不同的目的是不同的,它们在某些情况下可能看起来完全相同(CRUD场景)。

+0

有关域对象结构的好处理想情况下不受持久性机制的影响。谢谢! – 2014-11-05 11:15:35

+4

另请参阅Vaughn Vernon的最新“使用DDD和实体框架建模聚合体”https://vaughnvernon.co/?p=879 – JefClaes 2014-11-05 11:19:01