Automapper:如何不是从复杂类型重复映射配置基类 [英] Automapper: How to not repeat mapping config from complex type to base class

查看:1179
本文介绍了Automapper:如何不是从复杂类型重复映射配置基类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一大堆的DTO类,从这个继承 CardBase

I have a bunch of DTO classes that inherit from this CardBase:

// base class
public class CardBase
{
  public int TransId {get; set; }
  public string UserId  { get; set; }
  public int Shift { get; set; }
}

// one of the concrete classes
public class SetNewCardSettings : CardBase
{
  // specific properties ...
}

在我的MVC项目我有一个 AuditVm一堆视图模型复杂类型具有 CardBase 的相同属性:

In my MVC project I have a bunch of view models with a AuditVm complex type that has the same properties of CardBase:

public class AuditVm
{
  public int TransId {get; set; }
  public string UserId  { get; set; }
  public int Shift { get; set; }
}

public class CreateCardVm : CardVm
{
  // specific properties here ...

  public AuditVm Audit { get; set }
}



这些视图模型不能从 AuditVm <继承/ code>,因为他们每个人已经有一个父。我以为我可以设置类似下面这样我就不必指定从 AuditVm 地图到 CardBase 我的映射有 AuditVm 作为一个复杂类型中的每个视图模型。但它不工作。我如何正确地从一个复杂类型到扁平化的类型与基类属性映射

Those view models cannot inherit from AuditVm because each of them already has a parent. I thought I could setup my mapping like below so I would not have to specify the map from AuditVm to the CardBase for every view model that has AuditVm as a complex type. But it is not working. How do I properly map from a complex type to a flatten type with properties on the base class?

  Mapper.CreateMap<AuditorVm, CardBase>()
    .Include<AuditorVm, SetNewCardSettings>();

  // this does not work because it ignores my properties that I map in the second mapping
  // if I delete the ignore it says my config is not valid
  Mapper.CreateMap<AuditorVm, SetNewCardSettings>()
    .ForMember(dest => dest.Temp, opt => opt.Ignore())
    .ForMember(dest => dest.Time, opt => opt.Ignore());

  Mapper.CreateMap<CreateCardVm, SetNewCardSettings>()
     // this gives me an error
    .ForMember(dest => dest, opt => opt.MapFrom(src => Mapper.Map<AuditorVm, SetNewCardSettings>(src.Auditor)));

    // I also tried this and it works, but it does not map my specific properties on SetNewCardSettings
    //.ConvertUsing(dest => Mapper.Map<AuditorVm, SetNewCardSettings>(dest.Auditor));



更新:这里
是小提琴的 https://dotnetfiddle.net/iccpE0

推荐答案

.INCLUDE 是一个非常特殊的情况下 - 你有两个相同结构的类层次结构要映射,例如:

.Include is for a very specific case--you have two identically-structured class hierarchies you'd like to map, for example:

public class AEntity : Entity { }

public class BEntity : Entity { }

public class AViewModel : ViewModel { }

public class BViewModel : ViewModel { }

Mapper.CreateMap<Entity, ViewModel>()
    .Include<AEntity, AViewModel>()
    .Include<BEntity, BViewModel>();

// Then map AEntity and BEntity as well.



所以,除非你有这种情况, .INCLUDE 不是用正确的事

我认为最好的办法是使用 ConstructUsing

I think your best bet is to use ConstructUsing:

 Mapper.CreateMap<AuditVm, CardBase>();

 Mapper.CreateMap<AuditVm, SetNewCardSettings>()
     .ConstructUsing(src => 
          {
              SetNewCardSettings settings = new SetNewCardSettings();
              Mapper.Map<AuditVm, CardBase>(src, settings);
              return settings;
          })
     .IgnoreUnmappedProperties();

 Mapper.CreateMap<CreateCardVm, SetNewCardSettings>()
     .ConstructUsing(src => Mapper.Map<SetNewCardSettings>(src.Audit))
     .IgnoreUnmappedProperties();



我也注册成立的这个答案的扩展方法忽略所有未映射属性。由于我们使用 ConstructUsing ,AutoMapper不知道,我们已经采取了这些属性的照顾。

I've also incorporated this answer's extension method to ignore all unmapped properties. Since we're using ConstructUsing, AutoMapper doesn't know that we've already taken care of those properties.

更新小提琴: https://dotnetfiddle.net/6ZfZ3z

这篇关于Automapper:如何不是从复杂类型重复映射配置基类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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