用于将包含子集合的DTO映射回域模型的设计模式

时间:2011-01-03 19:20:45

标签: asp.net asp.net-mvc entity-framework automapper

我一直在使用AutoMapper将我的域模型映射到我的DTO,以及将我的DTO映射回域模型的时间最长。

我正在使用EF4作为我的ORM,当映射的模型包含需要添加/更新/删除的子集合时,这种映射变得非常难看。随着我的项目向前推进,我越来越多地遇到这个问题:博客文章的照片,订单的包裹等等。

当从DTO->域模型开始时,我最终必须添加一个BeforeMap调用,从域模型的集合中删除所有实体,然后为集合中添加一个自定义ValueResolver,从中获取每个实体的PK DTO,从数据库中获取它(以便实体框架不认为我正在添加新实体),并将其重新添加到域模型的集合中,然后将任何更新应用于各个字段。

这是一个非常难看的解决方案,但我尝试手动处理更新这些集合也是如此。有没有人对更清洁的方法有任何建议?

4 个答案:

答案 0 :(得分:3)

您可能希望使用ValueInjecter代替AutoMapper来实现此功能。看看这两个制造商所称的问题AutoMapper vs ValueInjecter。我没有亲自使用过Value Injecter,但它是为了做你想做的事而建的。 AutoMapper更适合展平,但AutoMapper的作者承认它不是“Unflattening”的好工具,这正是你想要做的。

答案 1 :(得分:1)

由于更新分离对象图的经验非常糟糕,我总是首先从数据库加载实际对象图并手动将我的DTO合并到此对象图中。我通常最终得到几个辅助Merger类,其方法是将DTO(或视图模型)合并到Domain对象。我还在寻找更好的解决方案。

我还尝试了解决方案,我没有先从数据库加载对象图。相反,我使用自定义适配器来构建分离的域对象图,将其附加到上下文并设置所有对象和关系的状态。但这是错误的,而且极其复杂的方式无法用于所有场景(如果没有关于初始状态的额外传输数据,则无法处理更新和子实体插入的组合。)

答案 2 :(得分:1)

在hibernate中有一个级联选项,其中更新来自子项..

我认为NHibernate有一个类似的cascadeAll选项。

答案 3 :(得分:1)

如果您可以假设DTO的儿童收藏品是假设的话 可能是最新版本,你实际上可以替换旧版本 用新的收集。

我们遇到了与NHibernate相同的问题 我们解决了这个问题:

  1. 使用ConstructWith将实体从数据库中拉出 dto的身份。
  2. 使用BeforeMap清除整个子集合(确保 对子项的引用也将设置为null。
  3. AutoMapper将自动复制新集合。
  4. 幸运的是,NHibernate足够聪明,只能应用更改,我不能 告诉EF是否也这样做。 这不是一个完美的解决方案,但它适用于简单的域模型。