簡體   English   中英

Automapper:如何不重復從復雜類型到基類的映射配置

[英]Automapper: How to not repeat mapping config from complex type to base class

我有一堆從此CardBase繼承的DTO類:

// 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

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繼承,因為它們每個都已經有一個父視圖。 我以為可以像下面那樣設置映射,因此CardBase為每個將AuditVm作為復雜類型的視圖模型指定從AuditVmCardBase的映射。 但這是行不通的。 如何正確地將復雜類型映射到具有基類屬性的扁平類型?

  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適用於非常特殊的情況-您有兩個要映射的結構相同的類層次結構,例如:

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

 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不知道我們已經處理了這些屬性。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM