C#中如何使用AutoMapper映射含嵌套List属性的对象
AutoMapper 实现A到C对象映射的方案
不需要手动编写循环遍历逻辑,通过AutoMapper的自定义成员映射配置即可直接完成需求,具体实现如下:
- 核心思路:在配置A到C的映射规则时,针对目标类型的
MapAddressData集合属性做自定义投影,把源类型A的Name属性值透传到集合内的每一个MapAddressData实例上,地址类的同名属性可自动匹配映射。
映射配置代码
using AutoMapper; // 初始化Mapper配置 var mapperConfig = new MapperConfiguration(cfg => { // 先配置B到MapAddressData的基础映射,同名属性自动完成匹配 cfg.CreateMap<B, MapAddressData>(); // 配置A到C的映射规则 cfg.CreateMap<A, C>() // id无对应源字段,可根据业务需求选择忽略或指定映射逻辑 .ForMember(dest => dest.id, opt => opt.Ignore()) // DateCreated可直接指定映射为当前时间,有其他逻辑可自行调整 .ForMember(dest => dest.DateCreated, opt => opt.MapFrom(_ => DateTime.Now)) // 核心配置:处理地址集合的映射,自动把父级Name赋值给每个地址项 .ForMember(dest => dest.MapAddressData, opt => opt.MapFrom((src, _, _, context) => { // 先通过AutoMapper完成B集合到MapAddressData集合的基础映射 var addressItems = context.Mapper.Map<List<MapAddressData>>(src.Address); // 给所有地址项统一赋值父级的Name addressItems.ForEach(item => item.Name = src.Name); return addressItems; }) ); }); // 开发环境可加这行校验配置合法性,提前发现属性不匹配问题 mapperConfig.AssertConfigurationIsValid(); var mapper = mapperConfig.CreateMapper();
使用方式
直接传入源类型A的实例调用Map方法即可得到目标类型C的实例,不需要额外做循环处理:
// 测试源数据 var source = new A { Name = "测试用户", Address = new List<B> { new() { streetName = "文三路", Number = 100 }, new() { streetName = "教工路", Number = 259 } } }; // 执行映射 var target = mapper.Map<C>(source);
映射效果说明
映射完成后,target.MapAddressData会生成2个MapAddressData实例:
- 两个实例的
Name属性均为源A的属性值"测试用户" - 两个实例的
streetName、Number分别对应源Address列表中两个B对象的属性值 target.DateCreated为映射执行时的当前时间
如果后续B类和MapAddressData类新增了同名同类型属性,上述配置不需要修改,AutoMapper会自动完成新属性的映射,维护成本更低。
内容的提问来源于stack exchange,提问作者Krypto456
相关产品推荐
相关产品推荐

