entity framework6.0下的ORM实体与域实体
我偶然发现了以下两篇文章的第一个和第二个 ,其中作者总结说ORM实体和领域实体不应混为一谈。
目前我正面临着这个问题,因为我使用Code First方法对EF 6.0进行编码。 我使用POCO类作为EF中的实体以及我的域/业务对象。 但是我发现自己经常处于这样一种情况:我只是因为EF框架强迫我这样做,才将一个属性定义为公共或导航属性。
这两篇文章的底线我不知道该怎么办? 我真的应该创build一个实例框架的CustomerEF类和我的域的CustomerD? 然后创build一个存储库,使用CustomerD映射到CustomerEF做一些查询,然后将接收到的CustomerEF映射回到CustomerD。 我以为EF是关于将我的域实体映射到数据的。
所以请给我一些build议。 我忽略了EF能够提供给我的一个重要的东西吗? 或者这是一个EF不能完全解决的问题? 在后一种情况下,解决这个问题的好方法是什么?
我同意这些post的总体思路。 ORM类模型首先是数据访问层的一部分(即使它是由所谓的POCO组成)。 如果在持久性和商业逻辑(或任何其他问题)之间产生利益冲突,总是应该做出有利于持久性的决定。
但是,作为软件开发人员,我们总是要在纯粹主义和实用主义之间取得平衡。 是否将持久性模型用作领域模型取决于许多因素:
-
开发团队的规模/一致性。 当整个团队知道只要ORM的要求就可以公开这个属性,但是不应该把它放到所有的地方,这可能不是什么大不了的事情。 如果每个人都知道(并服从)一个ID属性不被用在业务逻辑中,那么拥有ID可能不是什么大问题。 分散的,没有经验或没有纪律的团队可能需要更严格的代码分离。
-
业务逻辑问题和持久性问题之间的重叠。 面向对象的devise在类模型遵循SOLID原则时蓬勃发展。 但是这些原则并不一定与持久性问题相矛盾。 我的意思是,虽然关注点不同,但最终的要求可能非常相似。 例如,这两个问题可能需要有效的对象状态和正确的关联。
然而,可以有用例临时需要处于绝对不应存储的状态。 这可能是使用专用域类的原因。 另一个原因可能是实体模型无法完成最佳的职责划分。 例如,“将客户列入黑名单”的业务stream程可能需要散布在如此多的实体对象上的数据,以至于必须devise新的域类来封装数据和处理这些数据的方法。 换句话说:通过实体来做这件事将会违反Tell Do not Ask原则。
-
需要分层。 例如,如果数据访问层针对不同的数据库供应商,则可能需要由供应商特定的可互换部分组成(例如,考虑到Oracle和Sql Server之间的数据types的细微差异或利用供应商特定的function)。 使用持久性模型作为领域模型可能会将供应商特定的实现放到业务逻辑中。 那真的很糟糕。 那里的数据访问层应该是精确的那一层。
-
(很平凡)数据量。 创build对象需要时间和资源。 在业务案例中涉及“多”对象时,构build实体对象和域对象可能太昂贵了。
毫无疑问,更多。
所以我会一直试着成为一个实用主义者。 如果实体类做一个体面的工作,去做。 如果不匹配太大,请为业务逻辑的适当部分创build业务域。 我不会因为这是一个好的模式而盲目地遵循(任何)devise模式。 与文章中所说的相反,它需要大量的维护才能将实体模型映射到商业模型上。 当你发现自己创build了几乎与实体类相同的业务类时,现在是时候重新思考你在做什么了。