AutoMapper从4.2.1升级到6.x后new修饰属性映射值为null的解决方法
解决AutoMapper 5.x-6.x升级后派生类嵌套映射属性为null的问题
这个问题的核心原因是AutoMapper在5.0版本后调整了派生类到基类的映射逻辑:
- 在4.2.1中,当嵌套属性的实际类型是派生类、目标类型是基类时,AutoMapper会自动匹配你配置的
DealerOpportunity → DealerOpportunityLite这类映射规则,将派生类的属性(包括new覆盖的BranchCode)映射到基类属性。 - 而5.0+版本默认会直接将派生类实例赋值给基类属性(因为类型兼容),跳过了你配置的派生类映射规则,导致基类的
BranchCode因为没有被赋值而变为null。
全局解决方案(无需逐个添加ForMember)
由于你的项目中大量存在这种Xxx → XxxLite的继承结构,最高效的方式是通过反射自动配置基类映射的Include关系,让AutoMapper重新识别派生类的映射规则:
using System.Reflection; using AutoMapper; // 获取你的项目程序集(如果是多项目,需要调整为对应程序集) var targetAssembly = Assembly.GetExecutingAssembly(); Mapper.Initialize(cfg => { // 自动识别所有XxxLite基类及其对应的Xxx派生类 var liteBaseTypes = targetAssembly.GetTypes() .Where(t => t.Name.EndsWith("Lite") && !t.IsAbstract && t.IsClass); foreach (var baseType in liteBaseTypes) { // 查找对应的派生类(假设命名规则是XxxLite的派生类名为Xxx) var derivedTypeName = baseType.Name.Replace("Lite", ""); var derivedType = targetAssembly.GetTypes() .FirstOrDefault(t => t.IsClass && t.IsSubclassOf(baseType) && t.Name == derivedTypeName); if (derivedType != null) { // 配置基类→基类的映射,并包含派生类→基类的映射规则 cfg.CreateMap(baseType, baseType) .Include(derivedType, baseType); // 显式创建派生类→基类的映射(保持原有配置) cfg.CreateMap(derivedType, baseType); } } // 如果还有其他非XxxLite结构的映射,继续添加在这里 });
原理说明
通过Include方法,我们告诉AutoMapper:当处理基类类型的属性时,如果实际源对象是派生类,就使用预先配置的派生类→基类映射规则。这样在嵌套映射Opportunity → OpportunityLite时,AutoMapper会自动对DealerOpportunity属性应用DealerOpportunity → DealerOpportunityLite的映射,将派生类中new的BranchCode正确映射到基类的BranchCode属性上。
验证效果
运行你原来的测试代码,opp.DealerOpportunity.BranchCode会重新返回00168,和4.2.1版本的表现一致。
内容的提问来源于stack exchange,提问作者Giacomo Baccianti
相关产品推荐
相关产品推荐

