[英]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
作为复杂类型的视图模型指定从AuditVm
到CardBase
的映射。 但这是行不通的。 如何正确地将复杂类型映射到具有基类属性的扁平类型?
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.