mst*_*and 32 c# domain-driven-design entity-framework
我目前正在开展一个项目,我们开始使用DDD方法构建应用程序.我们现在首先考虑使用Entity Framework 6代码来帮助我们处理数据持久性.我的问题是如何最好地处理我们的域对象和EF实体之间的数据映射?
Mik*_*eSW 52
为了保持你的应用程序和你自己长期保持理智,永远不要开始你的DDD应用程序与持久性相关的问题(什么数据库,什么orm等)和总是(是的,总是)触摸数据库作为开发的最后阶段.
为您的域建模,实际上除持久性之外的任何其他模型.使用Repository模式使应用程序与Persistence分离.根据应用程序的需要定义repo接口,而不是绑定到db访问方法(这就是为什么你以后实现持久性的原因所以你不会想要将你的应用程序与持久性细节结合起来).
为repo接口编写内存实现,这通常意味着对列表或字典的简单包装,因此编写速度非常快,更重要的是更改.使用它们来实际测试和开发应用程序.
在接口稳定并且应用程序正常工作之后,就可以编写持久性实现,您可以使用任何您想要的内容.在你的情况下EF和它出现了映射.
现在,这是非常主观的,没有正确或错误的方式,你喜欢做事的方式.
就个人而言,我习惯使用纪念品,所以我从域对象中获取纪念品,然后手动将其映射到(微)ORM实体.我手动操作的原因是因为我的纪念品包含值对象.如果我将使用AutoMapper,我需要对它进行混淆,实质上我会编写更多代码而不是手动执行
更新(2015年)
这些天我只是Json的对象,要么使用特定的读取模型,要么将其直接存储在Data包含序列化对象的列的读取模型中.我仅在特定情况下使用Mementos.</ update>
根据您的域对象的外观以及EF实体的外观,您可以在大多数映射中使用automapper.但是,您将更难以测试您的存储库.
这取决于你如何做到这一点,找到适合你的风格的方式,它很容易维护,但从来没有设计或修改你的域对象更兼容或匹配ORM实体.它不是关于更改数据库或ORM,而是将域(以及应用程序的其余部分)与持久性详细信息(ORM所在)正确分离.
因此,抵制重复使用其他层的实现细节的诱惑.应用程序在层中构造的原因是因为您需要解耦.保持这种方式.
Ily*_*kin 18
为什么不直接使用EF实体作为域对象,因为您正在考虑首先使用Entity Framework 6代码?首先,您设计域模型然后设计数据库结构.
我一直在使用NHibernate并且相信在EF中你也可以指定从DB表到POCO对象的映射规则,尤其是EF6.在EF实体上开发另一个抽象层是一项额外的工作.让ORM负责.
我不同意这篇文章,你可能会读到"带有AutoMapper和Repository Pattern的实体框架5",还有很多其他文章,人们只是将EF实体用作Domain对象:
当您开始构建表示层并面对大量UI特定视图模型时, AutoMapper肯定会帮助您.当没有公共设置器时,它对于构建贫血模型很有用,并且对于真实的Domain对象有点无用.
有一个古老的职位由吉米·博加德"的情况下,在AutoMapper双向映射",他告诉"There is no two-way mapping because we never need two-way mapping."
那么我们使用AutoMapper的目的是什么?我们的五个档案包括:
- 从Domain到ViewModel(MVC的强类型视图模型)
- 从Domain到EditModel(MVC中表单的强类型视图模型)
- 从EditModel到CommandMessages - 从松散类型的EditModel转换为强类型的,分解的消息.单个EditModel可能会生成六个消息.
- 从Domain到ReportModel - 强类型Telerik报告
- 从域到EDI模型 - 用于生成EDI报告的展平模型
当我自己研究这个主题时,我发现我认为大多数使用或推荐使用 EF POCO 作为域对象的开发人员根本没有必要使用 DDD。DDD 是复杂域逻辑的推荐方法,当您具有复杂的域逻辑时,域逻辑和数据存储结构不太可能有 1:1 的映射。确实,在很多情况下,您将拥有与数据库设计结构类似的域对象,但是随着您的域变得更加复杂,您会发现许多域实体都需要偏离数据的方式物理存储。如果您发现自己想要使用自动映射器,我也同意这一点 - 在这种情况下您可能也不需要 DDD。您的应用程序可能很简单,不会从 DDD 的复杂性中受益。请注意,DDD 不是一种架构或设计模式,它是一种构建软件以使用通用语言开发丰富领域模型的方法。
我在一个企业级系统上工作,一个例子是我们的文档业务逻辑。文档要存在,必须满足以下要求:
因此,文档的简单概念不仅涉及大量的数据库数据表,而且还存在大量的业务逻辑只是为了创建它而发生的。这种情况并不存在 1:1 的映射,而且由于我们的系统也有必须分离的功能模块,因此我们通过继承和装饰器模式拥有不同类型的 Document 业务实体。
我们还有一个包含大约 200 个数据库表的数据库。我们必须维护一个非常干净和优化的数据库。不可能根据数据库做出业务逻辑决策,反之亦然。它们必须是分开的,这样我们就可以根据各自的需求,以自己的方式维护它们。领域实体需要提供有意义的丰富领域模型,数据库必须优化、正确且快速。
您面临的挑战是一项复杂的挑战 - 不幸的是,构建软件并不是一项微不足道的任务,而且不幸的是,业务逻辑和“数据”实际上是一体的 - 因为缺一不可。碰巧的是,要真正构建软件,我们必须以一种有意义的方式处理这个问题,既要扩展功能,又要扩展性能。
所有这一切的挑战在于软件有如此多的需求。那么,如何拥有丰富的领域模型、使用像 EF 这样的 ORM,并且能够以不适合领域模型的方式解决数据查询等问题呢?如何在代码库不被搞砸的情况下做到这一点?
对于我来说,对于像 EF 这样的东西来说,这很大程度上意味着找到一种方法,能够轻松地从数据(EF 实体)创建域对象,同时支持工作单元模式、上下文、更改跟踪等。对我来说,这看起来像是一个域对象,可以访问工作单元内的实体,由上下文跟踪。这意味着您可以将单个实体加载到域对象中,或者在单个查询表达式中加载许多实体以提高性能,并且仍然使用 EF 来执行插入和更新的更改跟踪。
我解决这个问题的第一个方法实际上是使用 Active Record,它与 EF 非常适合。每个域实体都有自己的上下文,并管理所有用于创建、删除和更新的业务逻辑。对于 90% 的软件来说,这非常好,而且不存在性能问题。我们使用具有自己上下文的域服务来实现高级查询场景。我无法在这里描述我们的整个方法,因为它需要一个自己的博客,但是......
我现在也在研究一种不使用 Active Record 的方法。我认为存储库是关键,能够加载许多并处理查询场景,以及可能的规范。
但我的观点是,我相信如果你真的需要 DDD,你的数据层和领域层应该完全分开,如果你不这么认为,你可能不需要 DDD。
| 归档时间: |
|
| 查看次数: |
23921 次 |
| 最近记录: |