如何在AutoMapper中为数组对象映射值:父属性赋值给子数组元素
AutoMapper配置:将ParentDto的StockNumber赋值给子数组中每个Supplier的StockNumber
需要实现从ParentDto到Parent的映射,核心需求是把ParentDto的StockNumber属性值,赋值给Parent对象中Suppliers列表内每一个Supplier的StockNumber属性。
实体代码
public class Parent { public int ParentId { get; set; } public long StockNumber { get; set; } public DateTimeOffset? EarliestPaymentDate { get; set; } public List<Supplier> Suppliers { get; set; } } public class Supplier { public int SupplierId { get; set; } public long StockNumber { get; set; } public int ParentId { get; set; } } public class ParentDto { public int ParentId { get; set; } public long StockNumber { get; set; } public DateTimeOffset? EarliestPaymentDate { get; set; } public List<Supplier> Suppliers { get; set; } } public class SupplierDto { public int SupplierId { get; set; } public long StockNumber { get; set; } public int ParentId { get; set; } }
错误尝试说明
你之前的写法无法实现需求,因为AutoMapper的ForMember无法直接绑定到集合元素的属性操作:
CreateMap<ParentDto, Parent>() .ForMember(dest => dest.EarliestPaymentDate, opt => opt.MapFrom(src => src.EarliestPaymentDateTime)) // 错误写法:无法直接对数组元素的属性进行映射 .ForMember(dest => dest.Suppliers.ForEach(x => x.StockNumber), opt => opt.MapFrom(src => src.StockNumber)) ;
正确解决方案
方法1:使用AfterMap完成后续赋值
先完成Parent和Suppliers的基础映射,再在映射结束后遍历子集合统一设置StockNumber:
CreateMap<ParentDto, Parent>() // 基础属性映射 .ForMember(dest => dest.EarliestPaymentDate, opt => opt.MapFrom(src => src.EarliestPaymentDateTime)) // 自动映射Suppliers的同名属性 .ForMember(dest => dest.Suppliers, opt => opt.MapFrom(src => src.Suppliers)) // 映射完成后批量设置子元素的StockNumber .AfterMap((src, dest) => { dest.Suppliers?.ForEach(supplier => supplier.StockNumber = src.StockNumber); });
方法2:结合子级映射与上下文传递(适用于ParentDto.Suppliers为SupplierDto的场景)
如果ParentDto中的Suppliers实际是List<SupplierDto>,可以通过自定义解析逻辑传递父级值:
- 先定义子级映射,忽略原
StockNumber:
CreateMap<SupplierDto, Supplier>() .ForMember(dest => dest.StockNumber, opt => opt.Ignore());
- 在父级映射中解析生成带父级
StockNumber的子集合:
CreateMap<ParentDto, Parent>() .ForMember(dest => dest.EarliestPaymentDate, opt => opt.MapFrom(src => src.EarliestPaymentDateTime)) .ForMember(dest => dest.Suppliers, opt => opt.ResolveUsing((src, dest, member, context) => { return src.Suppliers?.Select(dto => { var supplier = context.Mapper.Map<Supplier>(dto); supplier.StockNumber = src.StockNumber; return supplier; }).ToList(); }));
内容的提问来源于stack exchange,提问作者GThree
相关产品推荐
相关产品推荐

