AutoMapper从两个源映射表达式引发异常问题求助
解决AutoMapper双源对象映射与反向映射问题
刚好我之前处理过类似的场景,结合你用的Asp.Net Core 2.0和AutoMapper 6.2.2,给你整理完整的配置和实现步骤:
首先先补全你的模型类(添加了属性类型,方便实际测试):
public class UserA { public int CustomerId { get; set; } public string CustomerName { get; set; } } public class UserB { public int CustomerId { get; set; } public string CustomerEmail { get; set; } } public class UserViewModel { public int Id { get; set; } public string CustomerName { get; set; } public string CustomerEmail { get; set; } }
一、正向映射:从UserA+UserB到UserViewModel
AutoMapper 6.x支持直接从多个源对象映射到单个目标对象,你只需要在Profile配置里明确每个目标成员的来源:
public class MappingProfile : Profile { public MappingProfile() { // 配置双源映射到UserViewModel CreateMap<object[], UserViewModel>() .ForMember(dest => dest.Id, opt => opt.MapFrom(src => ((UserA)src[0]).CustomerId)) // 这里要确保两个源的CustomerId一致,或者根据业务需求选择其中一个 .ForMember(dest => dest.CustomerName, opt => opt.MapFrom(src => ((UserA)src[0]).CustomerName)) .ForMember(dest => dest.CustomerEmail, opt => opt.MapFrom(src => ((UserB)src[1]).CustomerEmail)); // 另一种灵活方案:分开配置单源到目标的映射,再手动合并 // CreateMap<UserA, UserViewModel>() // .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.CustomerId)); // CreateMap<UserB, UserViewModel>(); } }
使用的时候,直接传入两个源对象的数组即可:
var userA = new UserA { CustomerId = 1, CustomerName = "John Doe" }; var userB = new UserB { CustomerId = 1, CustomerEmail = "john@example.com" }; var viewModel = _mapper.Map<UserViewModel>(new object[] { userA, userB });
如果用分开配置单源的方式,需要手动合并属性:
var viewModel = _mapper.Map<UserViewModel>(userA); _mapper.Map(userB, viewModel);
二、反向映射:从UserViewModel到UserA/UserB
反向映射需要分别创建从ViewModel到两个源模型的映射配置,把ViewModel的属性拆分到不同类中:
public class MappingProfile : Profile { public MappingProfile() { // 正向映射(同上) CreateMap<object[], UserViewModel>() .ForMember(dest => dest.Id, opt => opt.MapFrom(src => ((UserA)src[0]).CustomerId)) .ForMember(dest => dest.CustomerName, opt => opt.MapFrom(src => ((UserA)src[0]).CustomerName)) .ForMember(dest => dest.CustomerEmail, opt => opt.MapFrom(src => ((UserB)src[1]).CustomerEmail)); // 反向映射到UserA CreateMap<UserViewModel, UserA>() .ForMember(dest => dest.CustomerId, opt => opt.MapFrom(src => src.Id)) .ForMember(dest => dest.CustomerName, opt => opt.MapFrom(src => src.CustomerName)); // 反向映射到UserB CreateMap<UserViewModel, UserB>() .ForMember(dest => dest.CustomerId, opt => opt.MapFrom(src => src.Id)) .ForMember(dest => dest.CustomerEmail, opt => opt.MapFrom(src => src.CustomerEmail)); } }
使用反向映射的代码示例:
var viewModel = new UserViewModel { Id = 1, CustomerName = "John Doe", CustomerEmail = "john@example.com" }; var userA = _mapper.Map<UserA>(viewModel); var userB = _mapper.Map<UserB>(viewModel);
三、Asp.Net Core 2.0中注入AutoMapper
别忘了在Startup.cs里配置AutoMapper服务:
public void ConfigureServices(IServiceCollection services) { // 注册AutoMapper,扫描程序集里的Profile类 services.AddAutoMapper(typeof(MappingProfile)); // 其他服务配置... }
这样就能完美实现你需要的双源映射和反向映射功能了,要是有特殊业务逻辑,还可以在MapFrom里加入自定义转换逻辑哦。
内容的提问来源于stack exchange,提问作者Konrad
相关产品推荐
相关产品推荐

