Automapper:如何不是从复杂类型重复映射配置基类 [英] Automapper: How to not repeat mapping config from complex type to base class
问题描述
我有一大堆的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 $ C 。$ C>不是用正确的事
我认为最好的办法是使用 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屋!