c# – 将ViewModel投影回Model的最佳方法

考虑使用viewmodel:
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);

BTW:我只使用automapper将Model转换为viewmodel,但反之亦然,我总是面临错误.

解决方法

总体而言,这可能不是您正在寻找的答案,但这是AutoMapper作者的引用:

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?

相关文章

在项目中使用SharpZipLib压缩文件夹的时候,遇到如果目录较深,则压缩包中的文件夹同样比较深的问题。比...
项目需要,几十万张照片需要计算出每个照片的特征值(调用C++编写的DLL)。 业务流程:选择照片...
var array = new byte[4]; var i = Encoding.UTF8.GetBytes(100.ToString("x2"));//...
其实很简单,因为Combox的Item是一个K/V的object,那么就可以把它的items转换成IEnumerable<Dic...
把.net4.6安装包打包进安装程序。 关键脚本如下: 头部引用字符串对比库 !include "WordFunc....
项目需求(Winform)可以批量打印某个模板,经过百度和摸索,使用iTextSharp+ZXing.NetʿreeSp...