ORM 实体与实体框架6.0下的域实体

我偶然发现了以下两篇文章 首先第二,作者在其中总结说,ORM 实体和域实体不应该混为一谈。

当我使用代码优先的方法使用 EF 6.0编码时,我正好遇到了这个问题。我使用 POCO 类作为 EF 中的实体以及我的域/业务对象。但是我发现自己经常遇到这样的情况: 我将一个属性定义为公共属性,或者将一个导航属性定义为虚拟属性,仅仅是因为 EF 框架迫使我这样做。

我不知道这两篇文章的底线是什么?例如,我是否应该为实体框架创建 CustomerEF 类,为我的域创建 CustomerD。然后创建一个使用 CustomerD 的存储库,将其映射到 CustomerEF,执行一些查询,然后将接收到的 CustomerEF 映射回 CustomerD。我认为 EF 就是将我的域实体映射到数据。

所以请给我一些建议。我是否忽略了 EF 能够提供给我的一件重要的事情?或者这是一个 EF 无法完全解决的问题?在后一种情况下,处理这个问题的好方法是什么?

18433 次浏览

我同意这些职位的总体思路。ORM 类模型首先是数据访问层的一部分(即使它由所谓的 POCO 组成)。如果持久性和业务逻辑(或任何其他关注点)之间出现任何利益冲突,应该始终做出有利于持久性的决策。

然而,作为软件开发人员,我们必须在纯粹主义和实用主义之间取得平衡。是否使用持久性模型作为领域模型取决于以下几个因素:

  • 开发团队的规模/一致性。当整个团队都知道属性可以仅仅因为 ORM 需求而是公共的,但是不应该到处设置,这可能不是一个大问题。如果每个人都知道(并遵守)在业务逻辑中不使用 ID 属性,那么使用 ID 可能不是什么大问题。一个分散的、没有经验的或者没有纪律的团队可能需要更严格的代码隔离。

  • 业务逻辑关注点和持久性关注点之间的重叠。当一个类模型遵循 很可靠原则时,面向对象设计就会蓬勃发展。但是,这些原则并不一定与持久性问题相冲突。我的意思是,尽管关注点不同,但最终它们的结果需求可能非常相似。例如,这两个问题都可能需要有效的对象状态和正确的关联。

    然而,在某些用例中,对象需要暂时处于绝对不应该存储的状态。这可能是使用专用域类的一个原因。另一个原因可能是实体模型无法实现最佳的职责划分。例如,业务流程“黑名单客户”可能需要分散在许多实体对象上的数据,因此必须设计新的域类来封装数据和处理这些数据的方法。换句话说: 实体这样做将违反 告诉别人不要问原则。

  • 需要分层。例如,如果数据访问层面向不同的数据库供应商,那么它可能必须由特定于供应商的可互换部分组成(例如,解释 Oracle 和 Sql Server 之间数据类型的细微差异,或者利用特定于供应商的特性)。使用持久性模型作为域模型可能会将特定于供应商的实现引入到业务逻辑中。那就太糟糕了。那里的数据访问层应该正是那样,一个层。

  • (非常琐碎)数据量。创建对象需要时间和资源。当业务用例中涉及“许多”对象时,构建实体对象和域对象的开销可能太大。

毫无疑问,还有更多。

所以我总是努力成为一个实用主义者。如果实体类做得不错,那就去做吧。如果不匹配太大,则为业务逻辑的适当部分创建一个业务域。我不会盲目地遵循(任何)设计模式,仅仅因为它是一个好的模式。与文章中所说的相反,将实体模型映射到业务模型需要大量的维护工作。当您发现自己创建了无数的业务类,这些类与实体类几乎完全相同时,是时候重新考虑您正在做的事情了。