Automapper 多源类多属性映射到目标类单个属性的配置咨询
问题核心原因
你配置的ProductModel到Product的映射直接用了ForMember赋值Code属性,会直接覆盖前两步从ProductVariant、ProductStyle映射拼接好的Code值,这是属性被覆盖的根本原因。另外你拼接用的分隔符是-,不符合要求的#,且缺少Inventory到ProductStock的映射配置。
修正方案
1. 先修正目标类的语法错误
原来的Product类里List<ProductStock>属性缺少名称,先补上:
public class Product { public string Code { get; set; } public List<ProductStock> Stocks {get;set;} // 补上属性名 } public class ProductStock { public decimal Quantity { get; set; } }
2. 修正AutoMapper的Profile配置
把ProductModel映射的直接赋值改为AfterMap追加拼接,同时修正分隔符、补充Inventory的映射规则:
public class TestProfile : Profile { // 注入Inventory数据源用于匹配库存 public TestProfile(List<Inventory> inventories) { // ProductVariant映射:初始化Code为尺码 CreateMap<ProductVariant, Product>() .ForMember(o => o.Code, o => o.MapFrom(v => v.Size)) .ForMember(o => o.Stocks, o => o.Ignore()); // ProductStyle映射:拼接颜色到Code前 CreateMap<ProductStyle, Product>() .AfterMap((style, product) => { product.Code = string.Concat(style.Color, "#", product.Code); }) .ForMember(o => o.Stocks, o => o.Ignore()); // ProductModel映射:拼接款号到Code最前,同时匹配库存赋值 CreateMap<ProductModel, Product>() .AfterMap((model, product) => { product.Code = string.Concat(model.ModelNo, "#", product.Code); // 匹配对应款号的库存 var inv = inventories.FirstOrDefault(i => i.ModelNo == model.ModelNo); if(inv != null) { product.Stocks = new List<ProductStock> { new ProductStock { Quantity = inv.Quantity } }; } }); // 补充Inventory到ProductStock的基础映射 CreateMap<Inventory, ProductStock>(); } }
3. (可选优化)更简洁的映射逻辑
如果不需要强依赖AutoMapper的多层映射,直接在循环里生成目标对象逻辑更直观,不会出现属性覆盖问题,性能也更好:
public void Mapper(List<Inventory> inventories) { foreach (var model in this.Data()) { var currentInv = inventories.FirstOrDefault(i=>i.ModelNo == model.ModelNo); foreach (var style in model.Styles) { foreach (var variant in style.Variants) { var product = new Product { // 直接按规则生成Code,完全可控 Code = string.Concat(model.ModelNo, "#", style.Color, "#", variant.Size), Stocks = currentInv != null ? new List<ProductStock> { new ProductStock { Quantity = currentInv.Quantity } } : new List<ProductStock>() }; products.Add(product); } } } }
测试输出
按你提供的测试用例,最终生成的Product的Code属性分别为:
model1#BLUE#Lmodel1#RED#Mmodel1#RED#S
同时Stocks属性的Quantity会自动匹配Inventory中对应款号的库存值。
内容的提问来源于stack exchange,提问作者Cowa
相关产品推荐
相关产品推荐

