C#使用AutoMapper映射继承类嵌套属性报错解决方法
问题原因分析
- 第一种
ConvertUsing+Select写法报错核心原因:PrevData是单个FooClass类型实例,并非集合类型,Select()是LINQ面向IEnumerable集合提供的扩展方法,单个对象不存在该方法定义。同时代码中引用了不存在的varData属性,C类中对应嵌套属性名是data,即使是集合场景也会因属性名不匹配触发额外错误。 - 第二种
ForMember直接映射子属性报错核心原因:AutoMapper的ForMember()API默认仅支持配置目标类型的顶级直接成员,不支持直接对嵌套子对象的深层属性做映射配置,这是API本身的设计限制。
可行实现方案
以下三种方案都可以完成映射需求,可根据自己的代码场景选择:
方案1:使用ForPath实现嵌套属性映射
这是最贴合官方报错提示的写法,注意需要先初始化嵌套的data属性,避免映射时触发空引用异常:
CreateMap<GetData, C>() // 初始化嵌套Data实例,避免空引用 .ForMember(dest => dest.data, opt => opt.MapFrom(_ => new Data())) // 用ForPath配置嵌套属性映射规则 .ForPath(dest => dest.data.var_c, opt => opt.MapFrom(src => src.PrevData.varC)) .ForPath(dest => dest.data.var_d, opt => opt.MapFrom(src => src.PrevData.varD)) .ForMember(dest => dest.var_e, opt => opt.MapFrom(src => src.PrevData.varE));
注意:如果使用的AutoMapper版本过低不支持ForPath,换后面两种方案即可。
方案2:使用ConvertUsing自定义全量映射逻辑
这种写法最直白,映射逻辑完全由自己控制,不存在API限制,也不需要额外处理嵌套属性的配置规则,适合简单映射场景:
CreateMap<GetData, C>() .ConvertUsing(src => new C { var_e = src.PrevData.varE, data = new Data { var_c = src.PrevData.varC, var_d = src.PrevData.varD } });
如果业务中PrevData可能为null,可以在逻辑中补充空值判断,避免抛出空引用异常。
方案3:拆分映射规则复用配置
如果后续其他地方也需要用到FooClass/B类到Data、C的映射,可以拆分映射配置,让AutoMapper按约定自动完成匹配,减少重复代码:
// 配置B类到Data类的映射,FooClass作为子类会自动继承该映射规则 CreateMap<B, Data>() .ForMember(dest => dest.var_c, opt => opt.MapFrom(src => src.varC)) .ForMember(dest => dest.var_d, opt => opt.MapFrom(src => src.varD)); // 配置B类到C类的映射 CreateMap<B, C>() .ForMember(dest => dest.data, opt => opt.MapFrom(src => src)) .ForMember(dest => dest.var_e, opt => opt.MapFrom(src => src.varE)); // 配置GetData到C的映射,直接复用B到C的映射规则 CreateMap<GetData, C>() .ConstructUsing(src => Mapper.Map<C>(src.PrevData));
补充注意点
- 配置映射时注意字段/属性名的大小写匹配,之前代码中出现的
VarC、varData都和实际类定义的名称不一致,即使映射逻辑正确也会触发错误。 - 如果不想在配置中手动初始化嵌套对象,也可以在C类的构造函数中直接初始化
data属性,省去空值处理的步骤。
内容的提问来源于stack exchange,提问作者Krypto456
相关产品推荐
相关产品推荐

