如何使用AutoMapper将两个嵌套源对象合并为单个目标对象
解决方案
你可以通过AutoMapper的Map重载方法(传入已有目标对象复用,而非新建对象)实现两个源子对象的属性合并,以下是两种常用实现方案:
方案1:直接在ForMember中定义合并逻辑
保留你原有两个子对象的映射配置,仅修改Source到Destination的映射即可:
// 原有子对象映射保持不变 Mapper.CreateMap<SourceSubItemA, DestinationSubItem>() .ForMember(dest => dest.propertyA, opt => opt.MapFrom(src => src.subPropertyA)); Mapper.CreateMap<SourceSubItemB, DestinationSubItem>() .ForMember(dest => dest.propertyB, opt => opt.MapFrom(src => src.subPropertyB)); // 改写Source到Destination的映射规则 Mapper.CreateMap<Source, Destination>() .ForMember(dest => dest.destItem, opt => opt.MapFrom(src => { // 空值兼容处理 if (src.subItemA == null && src.subItemB == null) return null; // 先映射subItemA的属性到新的目标子对象 var destSubItem = Mapper.Map<DestinationSubItem>(src.subItemA); // 将subItemB的属性映射到已有的目标子对象上,不会新建实例,仅覆盖匹配属性 Mapper.Map(src.subItemB, destSubItem); return destSubItem; }));
调用方式无需修改,执行Mapper.Map<Destination>(sourceObject)即可得到同时填充两个属性的目标对象。
方案2:使用AfterMap钩子实现
如果希望映射规则更清晰,也可以用AfterMap后置处理完成属性合并:
Mapper.CreateMap<Source, Destination>() .ForMember(dest => dest.destItem, opt => opt.MapFrom(src => src.subItemA)) .AfterMap((src, dest) => { if (src.subItemB != null && dest.destItem != null) { Mapper.Map(src.subItemB, dest.destItem); } });
注意(高版本AutoMapper适配)
AutoMapper 9.0及以上版本已废弃静态Mapper.CreateMapAPI,需使用Profile类配置映射,示例如下:
public class MergeProfile : Profile { public MergeProfile() { CreateMap<SourceSubItemA, DestinationSubItem>() .ForMember(dest => dest.propertyA, opt => opt.MapFrom(src => src.subPropertyA)); CreateMap<SourceSubItemB, DestinationSubItem>() .ForMember(dest => dest.propertyB, opt => opt.MapFrom(src => src.subPropertyB)); CreateMap<Source, Destination>() .ForMember(dest => dest.destItem, opt => opt.MapFrom(src => { if (src.subItemA == null && src.subItemB == null) return null; var subItem = src.subItemA == null ? new DestinationSubItem() : Mapper.Map<DestinationSubItem>(src.subItemA); if (src.subItemB != null) Mapper.Map(src.subItemB, subItem); return subItem; })); } } // 注册并使用 var config = new MapperConfiguration(cfg => cfg.AddProfile<MergeProfile>()); var mapper = config.CreateMapper(); var result = mapper.Map<Destination>(sourceObject);
内容的提问来源于stack exchange,提问作者HTT
相关产品推荐
相关产品推荐

