public class viewmodel { public int id {get;set;} public int a {get;set;} public int b {get;set;} }
和这样的原始模型:
public class Model { public int id {get;set;} public int a {get;set;} public int b {get;set;} public int c {get;set;} public virtual Object d {get;set;} }
每次我获得视图模型时,我必须将所有viewmodel属性逐个放入Model中.就像是 :
var model = Db.Models.Find(viewmodel.Id); model.a = viewmodel.a; model.b = viewmodel.b; Db.SaveChanges();
这总会导致很多问题.我甚至有时会忘记提及一些属性然后发生灾难!
我在寻找类似的东西:
Mapper.Map(model,viewmodel);
解决方法
I can’t for the life of me understand why I’d want to dump a DTO
straight back in to a model object.
我相信从viewmodel映射到Entity的最佳方法是不使用AutoMapper. AutoMapper是一个很好的工具,用于映射对象而不使用静态以外的任何其他类.否则,每个添加的服务都会使代码变得更加混乱和混乱,并且在某些时候您将无法跟踪导致您的字段更新,集合更新等的原因.
经常面临的具体问题:
>需要非静态类来为您的实体进行映射
您可能需要使用DbContext来加载和引用实体,您可能还需要其他类 – 一些将图像上传到您的文件存储的工具,一些用于密码的哈希/盐等非静态类等等…您要么必须以某种方式将它传递给automapper,在AutoMapper配置文件中注入或创建,这两种做法都非常麻烦.
>可能需要在同一viewmodel(Dto)上进行多次映射 – >实体对
对于相同的viewmodel-entity对,您可能需要不同的映射,具体取决于此实体是否为聚合,或者不是基于您是否需要引用此实体或引用和更新.总的来说这是可以解决的,但在代码中会产生很多不需要的噪音,甚至更难维护.
>非常脏的代码很难维护.
这个是关于原语(字符串,整数等)和手动映射引用,转换值等的自动映射.对于automapper,代码看起来很奇怪,你必须为属性定义映射(或者如果你喜欢隐式的自动化映射 – 当与ORM配对时也具有破坏性)并使用AfterMap,BeforeMap,Conventions,ConstructUsing等来映射其他属性,这使得更复杂的东西.
>复杂映射
当你必须进行复杂的映射时,比如从2个源类到1个目标类的映射,你将不得不进一步复杂化,可能会调用以下代码:
var target = new Target(); Mapper.Map(source1,target); Mapper.Map(source2,target); //etc..
该代码会导致错误,因为您无法将source1和source2映射到一起,并且映射可能取决于将源类映射到目标的顺序.如果您忘记进行1次映射,或者如果您的地图在1个属性上存在冲突的映射,那么我就不会说话,相互覆盖.
这些问题可能看起来很小,但是在我使用自动化库来将viewmodel / Dto映射到Entity的几个项目中,它比从未使用过更加痛苦.
以下是一些链接:
> Jimmy Bogard,author of AutoMapper about 2-way mapping for your entities
> A small article with comments about problems faced when mapping ViewModel->Entity with code examples
> SO中的类似问题:Best Practices For Mapping DTO to Domain Object?