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

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

问题描述

考虑拥有一个 ViewModel:

Consider having a 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 中.类似的东西:

Each time I get the 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 problems. I even sometimes forget to mention some properties and then disaster happens! I was looking for something like:

Mapper.Map(model, viewModel);

顺便说一句:我只使用 AutoMapper 将 Model 转换为 ViewModel,反之亦然,我总是遇到错误.

BTW: I use AutoMapper only to convert Model to ViewModel but vice-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 映射到实体的最佳方法不是为此使用 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、注入或在 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) -> Entity Pair 上进行多个映射

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

对于相同的视图模型-实体对,您可能需要不同的映射,具体取决于此实体是否是聚合,或者不是 + 基于您是否需要引用此实体或引用和更新.总的来说,这是可以解决的,但会导致代码中出现大量不必要的噪音,并且更难维护.

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.

这个是关于基元(字符串、整数等)和手动映射引用、转换值等的自动映射.自动映射器的代码看起来很奇怪,你必须为属性定义映射(或者不,如果你更喜欢隐式自动映射器映射 - 这在与 ORM 配对时也是破坏性的)并使用 AfterMap、BeforeMap、Constructions、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 映射到实体的几个项目中,它比从未使用它造成的痛苦要大得多.

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:

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

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