有条件地将一种源类型映射到两种目标类型

我有这样的源DTO

public class Member { public string MemberId {get;set;} public string MemberType {get;set;} public string Name {get;set;} } 

会员类型可以是“人”或“公司”。

还有两个这样的目的地类

 public class PersonMember { public int PersonMemberId {get;set;} public string Name {get;set;} } public class CompanyMember { public int CompanyMemberId {get;set;} public string Name {get;set;} } 

我想使用Automapper来检查MemberType在源类中的值,并根据该类型映射到两种目标类型之一。

我看到了有条件映射的例子,但它映射了它执行条件检查的字段。 我想检查条件并映射不同的字段。

 var config = new MapperConfiguration(cfg => { cfg.CreateMap() .ForMember(dest => dest.baz, opt => opt.Condition(src => (src.baz >= 0))); }); 

我的目标是这样的 –

 cfg.CreateMap() .ForMember(dest => PersonMember.PersonMemberId, opt => if the source.MemberType == "Person" perform mapping from MemberId, otherwise do nothing); cfg.CreateMap() .ForMember(dest => CompanyMember.CompanyMemberId, opt => if the source.MemberType == "Company" perform mapping from MemberId, otherwise do nothing); 

使用automapper,您必须在调用映射器上指定返回类型,例如。 mapper.Map(member) ,这告诉返回类型是PersonMember因此您无法返回PersonMember

你可以这样做:

 var configPerson = new MapperConfiguration(cfg => cfg.CreateMap()); var configCompany = new MapperConfiguration(cfg => cfg.CreateMap()); PersonMember personMember = null; CompanyMember companyMember = null; switch (member.MemberType ) { case "PersonMember": var mapper = configPerson.CreateMapper(); personMember = mapper.Map(member); break; case "CompanyMember": var mapper = configCompany.CreateMapper(); companyMember = mapper.Map(member); break; default: throw new Exception("Unknown type"); break; } 

或者您可以尝试将 object作为返回类型的自定义类型转换器 。

介绍一些基类Member 。 从新基类inheritancePersonMemberPersonMember

然后定义这些映射:

 cfg.CreateMap() .ConstructUsing((memberDto, context) => { switch (memberDto.MemberType) { case "PersonMember": return context.Mapper.Map(memberDto); case "CompanyMember": return context.Mapper.Map(memberDto); default: throw new ArgumentOutOfRangeException($"Unknown MemberType {memberDto.MemberType}"); } }); cfg.CreateMap() .ForMember(dest => PersonMember.PersonMemberId, opt => opt.MapFrom(src => src.MemberId)); cfg.CreateMap() .ForMember(dest => CompanyMember.CompanyMemberId, opt => opt.MapFrom(src => src.MemberId)); 

现在您可以使用_mapperInstance.Map(memberDto);进行映射_mapperInstance.Map(memberDto);

我看到了有条件映射的例子,但它映射了它执行条件检查的字段。 我想检查条件并映射不同的字段。

尝试使用这样的配置:

 cfg.CreateMap() .ForMember(dest => PersonMember.PersonMemberId, opt => { opt.Condition(src => src.MemberType == "Person"); opt.MapFrom(src => src.MemberId); }); cfg.CreateMap() .ForMember(dest => CompanyMember.CompanyMemberId, opt => { opt.Condition(src => src.MemberType == "Company"); opt.MapFrom(src => src.MemberId); }); 

如果您从不兼容的对象Id字段映射将设置为0

对于版本5及更高版本,您可以尝试以下代码:

 using System; using AutoMapper; namespace AutoMapOneToMulti { class Program { static void Main(string[] args) { RegisterMaps(); var s = new Source { X = 1, Y = 2 }; Console.WriteLine(s); Console.WriteLine(Mapper.Map(s)); Console.WriteLine(Mapper.Map(s)); Console.ReadLine(); } static void RegisterMaps() { Mapper.Initialize(cfg => cfg.AddProfile()); } } public class GeneralProfile : Profile { public GeneralProfile() { CreateMap(); CreateMap(); } } public class Source { public int X { get; set; } public int Y { get; set; } public override string ToString() { return string.Format("Source = X : {0}, Y : {1}", X, Y); } } public class Destination1 { public int X { get; set; } public int Y { get; set; } public override string ToString() { return string.Format("Destination1 = X : {0}, Y : {1}", X, Y); } } public class Destination2 { public int X { get; set; } public int Y { get; set; } public override string ToString() { return string.Format("Destination2 = X : {0}, Y : {1}", X, Y); } } } 

对于低于5的版本,您可以尝试这样做:

 using System; using AutoMapper; namespace AutoMapOneToMulti { class Program { static void Main(string[] args) { RegisterMaps(); var s = new Source { X = 1, Y = 2 }; Console.WriteLine(s); Console.WriteLine(Mapper.Map(s)); Console.WriteLine(Mapper.Map(s)); Console.ReadLine(); } static void RegisterMaps() { Mapper.Initialize(cfg => cfg.AddProfile()); } } public class GeneralProfile : Profile { protected override void Configure() { CreateMap(); CreateMap(); } } public class Source { public int X { get; set; } public int Y { get; set; } public override string ToString() { return string.Format("Source = X : {0}, Y : {1}", X, Y); } } public class Destination1 { public int X { get; set; } public int Y { get; set; } public override string ToString() { return string.Format("Destination1 = X : {0}, Y : {1}", X, Y); } } public class Destination2 { public int X { get; set; } public int Y { get; set; } public override string ToString() { return string.Format("Destination2 = X : {0}, Y : {1}", X, Y); } } } 

如果您想要动态function,请使用此扩展名:

 public static dynamic DaynamicMap(this Source source) { if (source.X == 1) return Mapper.Map(source); return Mapper.Map(source); } Console.WriteLine(new Source { X = 1, Y = 2 }.DaynamicMap()); Console.WriteLine(new Source { X = 2, Y = 2 }.DaynamicMap());