域驱动设计和实体框架中的实体应该是一样的吗?

时间:2014-11-04 15:33:25

标签: entity-framework architecture domain-driven-design entities

我第一次开始使用Entity Framework Code First,我对围绕域构建绿地应用程序的方式印象深刻,而不是围绕关系数据库表(这是我多年来的工作方式)。

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

我的问题是:这些相同的实体(即设计为实体框架)是否应与域驱动设计中的实体扮演相同的角色(即代表域的核心)?

4 个答案:

答案 0 :(得分:21)

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

<强> ORM

ORM就是为了弥合数据库中存在的关系数据模型与对象模型任何对象模型之间的差距。

由EF定义的实体具体是指任何对象,您希望将关系模型的某个子部分映射到(和从中)。事实证明,EF创建者希望通过命名实体来为这些人提供商业内涵,但最终没有任何东西会强迫你这样做。您可以映射到View Models,只关注它。

<强> DDD

从DDD的角度来看,没有&#34;设计了EF的实体&#34;。 DDD实体应该是持久性无知且不承担任何ORM的痕迹。域层对其对象的存储方式,位置,是否或何时不感兴趣。

两者相遇

两个正交概念相交的唯一点是当您的ORM映射所针对的对象模型恰好是您的域模型时。这可以通过EF调用&#34;代码优先&#34; (但实际上应该命名为常规ORM),指向生活在非域层中的单独EF映射文件中的DDD实体,并避免在实体类中直接使用EF工件(如数据注释)。使用Database First时这是不可能的,因为DDD&#34;纯度&#34;该交易的一部分将无法实现。

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

答案 1 :(得分:15)

他们不应该不同目的相同。 ORM实体是一个或多个表的外观,其目的是在关系表之上模拟OOP。域实体是关于定义域概念。如果您的域实体只是一个数据结构,那么您可以将其重用为EF实体,但这只是一个案例。

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

当您达到这一点时,您将知道您是否可以将您的DO重新用于ORM目的,或者您是否需要其他方式(例如纪念品)。

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

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

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

答案 2 :(得分:4)

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

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

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

还有另外两个可能有用的问题:

答案 3 :(得分:1)

嗯。那是我使用的方法。我已经看到很多其他人在做同样的事情。现在正在使用洋葱架构/模式来创建我的应用程序并使一切依赖于域实体让我的生活更轻松。因为每当我想改变例如处理我的数据库的图层时,我可以做到这一点而无需更改UI层(ASP.NET MVC应用程序,WPF应用程序......等)...我建议做同样的。

让我们等待其他帖子

我同意MikeSW的说法(第3回答)。当你设计你的域名实体时,你应该这样做而不关心谁将使用这些实体(ORM或任何其他任何用途的技术)。设计他们的想法记住:它们将是可重复使用的,将来不需要改变它们(希望如此)