将ViewModel投影回Model的最佳方法 [英] best way to project ViewModel back into Model

查看:82
本文介绍了将ViewModel投影回Model的最佳方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑使用ViewModel:

Consider having 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属性一一放入模型中.像这样的东西:

Each time I get view model I have to put all ViewModel properties one by one into Model. Something like :

var model = Db.Models.Find(viewModel.Id);
model.a = viewModel.a;
model.b = viewModel.b;
Db.SaveChanges();

这总是会引起很多问题.我什至有时忘了提到一些属性,然后灾难发生了! 我正在寻找类似的东西:

Which always cause lots of problem. I even sometimes forget to mention some properties and then disaster happens! I was looking for something like :

Mapper.Map(model, viewModel);

顺便说一句:我只使用自动映射器将模型转换为ViewModel,反之亦然,我总是会遇到错误.

BTW: I use automapper only to convert Model to ViewModel but in vise versa I always face errors.

推荐答案

总体而言,这可能并不是您所要查找的答案,但这是AutoMapper作者的话:

Overall that might be not the answer, that you are looking for, but here's a quote from AutoMapper author:

我一辈子都无法理解为什么我想放弃DTO 直接回到模型对象.

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是一个很棒的工具,可用于映射对象,而无需使用除静态以外的任何其他类.否则,代码会因添加的每项服务而变得越来越混乱,并且有时您将无法跟踪导致字段更新,集合更新等的原因.

I believe best way to map from ViewModel to Entity is not to use AutoMapper for this. AutoMapper is a great tool to use for mapping objects without using any other classes other than static. Otherwise, code gets messier and messier with each added service, and at some point you won't be able to track what caused your field update, collection update, etc.

经常遇到的特定问题:

  1. 需要非静态类为您的实体进行映射

  1. Need for non-static classes to do mapping for your entities

您可能需要使用DbContext来加载和引用实体,还可能需要其他类-一些将图像上传到文件存储中的工具,一些非静态类对密码进行哈希/盐处理,等等.您要么以某种方式将其传递到AutoMapper配置文件中进行自动映射,注入或创建,但这两种做法都是很麻烦的.

You might need to use DbContext to load and reference entities, you might also need other classes - some tool that does image upload to your file storage, some non-static class that does hashing/salt for password, etc etc... You either have to pass it somehow to automapper, inject or create inside AutoMapper profile, and both practices are pretty troublemaking.

可能需要在同一ViewModel(Dto)->实体对上进行多个映射

Possible need for multiple mappings over same ViewModel(Dto) -> Entity Pair

对于同一个viewmodel-entity对,您可能需要不同的映射,这取决于该实体是否是一个聚合,或者是否+,取决于您是否需要引用该实体或引用和更新.总体而言,这是可以解决的,但是会在代码中引起很多不必要的噪音,并且甚至更难以维护.

You might need different mappings for same viewmodel-entity pair, based on if this entity is an aggregate, or not + based on if you need to reference this entity or reference and update. Overall this is solvable, but causes a lot of not-needed noise in code and is even harder to maintain.

真正肮脏的代码,难以维护.

Really dirty code that's hard to maintain.

这是关于基元(字符串,整数等)的自动映射以及手动映射引用,转换后的值等的内容.对于automapper来说,代码看起来真的很奇怪,您必须为属性定义映射(或者,如果没有,请定义)首选隐式自动映射器映射-与ORM配对时也具有破坏性),并使用AfterMap,BeforeMap,Conferences,ConstructUsing等来映射其他属性,这使事情更加复杂.

This one is about automatic mapping for primitives (strings, integers, etc) and manual mapping references, transformed values, etc. Code will look really weird for automapper, you would have to define maps for properties (or not, if you prefer implicit automapper mapping - which is also destructive when paired with ORM) AND use AfterMap, BeforeMap, Conventions, ConstructUsing, etc.. for mapping other properties, which complicates stuff even more.

复杂映射

当您必须进行复杂的映射时(例如从2个以上的源类映射到1个目标类),您将不得不使事情变得更加复杂,可能会调用以下代码:

When you have to do complex mappings, like mapping from 2+ source classes to 1 destination class, you will have to overcomplicate things even more, probably calling code like:

var target = new Target();
Mapper.Map(source1, target);
Mapper.Map(source2, target);
//etc..

该代码会导致错误,因为您无法将source1和source2一起映射,并且映射可能取决于将源类映射到目标的顺序.如果您忘记做1个映射,或者您的地图在1个属性上有相互冲突的映射,并且相互覆盖,我不会说.

That code causes errors, because you cannot map source1 and source2 together, and mapping might depend on order of mapping source classes to target. And I'm not talking if you forget to do 1 mapping or if your maps have conflicting mappings over 1 property, overwriting each other.

这些问题看似很小,但是在一些项目中,我面临着使用自动映射库将ViewModel/Dto映射到Entity的麻烦,这比从未使用过的麻烦更多.

These issues might seem small, but on several projects where I faced usage of automapping library for mapping ViewModel/Dto to Entity, it caused much more pain than if it was never used.

以下是一些适合您的链接:

Here are some links for you:

  • 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
  • Similar question in SO: Best Practices For Mapping DTO to Domain Object?

这篇关于将ViewModel投影回Model的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆