考虑使用 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; }
}
每次获取 View 模型时,我都必须将所有 ViewModel
属性一一放入 Model
中。像这样的东西:
var model = Db.Models.Find(viewModel.Id);
model.a = viewModel.a;
model.b = viewModel.b;
Db.SaveChanges();
这总是会导致很多问题。我什至有时会忘记提及某些属性,然后灾难就发生了! 我在寻找类似的东西:
Mapper.Map(model, viewModel);
顺便说一句:我只使用 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 配置文件中注入(inject)或创建,这两种做法都很麻烦。
可能需要在同一个 ViewModel(Dto) -> 实体对上进行多个映射
对于相同的 View 模型实体对,您可能需要不同的映射,这取决于该实体是否是聚合,或者不是+基于您是否需要引用该实体或引用和更新。总的来说,这是可以解决的,但会在代码中产生很多不需要的噪音,而且更难维护。
非常脏的代码,很难维护。
这是关于基元(字符串、整数等)的自动映射和手动映射引用、转换后的值等。自动映射器的代码看起来真的很奇怪,您必须为属性定义映射(或者不定义,如果您更喜欢隐式自动映射器映射——与 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 映射到实体的几个项目中,这比从未使用它造成的痛苦要大得多。
这里有一些链接:
关于c# - 将 ViewModel 投影回模型的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35959968/