C# 使用Automapper如何按相同ID合并两个集合为一个新集合
AutoMapper 合并同ID双集合映射解决方案
AutoMapper 本身仅负责对象属性的映射逻辑,不内置集合关联匹配能力,你可以通过以下两种方案实现需求:
方案1:先关联双集合再映射(推荐)
先通过 LINQ 对两个源集合按ID做关联,生成包含双方所有需要属性的中间对象,再映射到目标类型,实现逻辑更直观易维护。
示例代码如下:
// 假设你的第二个源集合为otherTaxSources,类型为IEnumerable<OtherTaxSource>,与PaymentsReport共用Id属性 var config = new MapperConfiguration(c => { c.AllowNullCollections = true; c.AllowNullDestinationValues = true; // 配置中间匿名类到目标类型的映射,AutoMapper会自动按属性名匹配 c.CreateMap<(PaymentsReport Report, OtherTaxSource TaxSource), TaxCalculationData>(); }); var mapper = new Mapper(config); // 按Id关联两个集合,按需选择左联/内联/右联,示例为保留所有PaymentsReport的项 var joinedItems = PaymentsReport.GroupJoin( otherTaxSources, report => report.Id, tax => tax.Id, (report, taxGroup) => (Report: report, TaxSource: taxGroup.FirstOrDefault()) ); // 直接映射关联后的集合得到最终结果 IEnumerable<TaxCalculationData> taxCalculationsX = mapper.Map<IEnumerable<TaxCalculationData>>(joinedItems).ToList();
方案2:增量映射补全属性
如果你已经完成了第一个集合的映射,需要用第二个集合的属性补全已有目标对象的缺省值,可以使用AutoMapper的Map(source, destination)重载,该重载不会新建目标对象,只会覆盖对应属性值:
示例代码如下:
var config = new MapperConfiguration(c => { c.AllowNullCollections = true; c.AllowNullDestinationValues = true; c.CreateMap<PaymentsReport, TaxCalculationData>(); // 新增第二个源类型到目标类型的映射 c.CreateMap<OtherTaxSource, TaxCalculationData>() // 可选配置:仅当目标属性为null时才赋值,避免覆盖已有值 .ForAllMembers(opts => opts.Condition((src, dest, srcVal) => srcVal != null)); }); var mapper = new Mapper(config); // 第一步:从集合A映射得到初始目标集合 IEnumerable<TaxCalculationData> taxCalculationsX = mapper.Map<IEnumerable<TaxCalculationData>>(PaymentsReport).ToList(); // 第二步:按ID匹配集合B的项,增量映射补全属性 var taxDict = otherTaxSources.ToDictionary(x => x.Id); foreach (var item in taxCalculationsX) { if (taxDict.TryGetValue(item.Id, out var taxSource)) { mapper.Map(taxSource, item); } }
注意事项
- 关联匹配前建议先排查两个源集合的ID重复、空值问题,避免运行时报错
- 若两个源类型存在同名但取值逻辑不同的属性,可以在
CreateMap中通过ForMember单独指定映射规则
内容的提问来源于stack exchange,提问作者Adam Rudzinski
相关产品推荐
相关产品推荐

