You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

AutoMapper嵌套对象映射抛出异常问题(.NET Core 5 + AutoMapper 10.1.1)

解决AutoMapper嵌套对象第二层映射失败的问题

我来帮你分析下这个问题——你现在的核心错误是试图在父级对象的映射规则里直接操作嵌套集合的子属性,这完全不符合AutoMapper的设计逻辑。AutoMapper需要为每一层的对象单独配置映射规则,而不是跨层级直接指定子集合的子属性。

问题根源

你写的这行代码是不被AutoMapper支持的:

.ForMember(dataView => dataView.Enforcements.Select(x=>x.Contraventions), opt => opt.MapFrom(dataModel => GetContraventions(dataModel.Enforcements.ToList())))

ForMember只能针对目标对象的直接属性,而Enforcements.Select(x=>x.Contraventions)是嵌套集合里的子属性,AutoMapper无法识别这种写法,自然会抛出异常。

正确解决方案

我们需要为每一层对象单独配置映射规则,让AutoMapper逐层处理嵌套对象:

  1. EnforcementEnforcementDataView创建独立的映射规则,在这个层级处理Contraventions的数据源
  2. 调整GetContraventions方法,让它接收单个Enforcement实例(因为每个Enforcement对应自己的Contraventions集合)
  3. 父级映射只需要处理直接属性,嵌套集合会自动使用子层级的映射规则

修改后的完整配置代码

public class SiteContraventionsProfile : Profile {
    public SiteContraventionsProfile() {
        // 第一层映射:Site -> SiteContraventionDataView
        CreateMap<Site, SiteContraventionDataView>()
            .ForMember(dest => dest.SiteId, opt => opt.MapFrom(src => src.SiteId))
            .ForMember(dest => dest.SiteName, opt => opt.MapFrom(src => src.SiteName))
            .ForMember(dest => dest.Enforcements, opt => opt.MapFrom(src => src.Enforcements));
        // 这里只需要映射Enforcements集合,AutoMapper会自动用下面的规则处理每个元素

        // 第二层映射:Enforcement -> EnforcementDataView
        CreateMap<Enforcement, EnforcementDataView>()
            .ForMember(dest => dest.EnforcementId, opt => opt.MapFrom(src => src.EnforcementId))
            .ForMember(dest => dest.Contraventions, opt => opt.MapFrom(src => GetContraventions(src)));
        // 在这里专门处理单个Enforcement的Contraventions属性
    }

    // 修改方法:接收单个Enforcement,返回对应的Contraventions列表
    private List<Contravention> GetContraventions(Enforcement enforcement) {
        List<Contravention> contraventions = new List<Contravention>();
        // 根据你的实际业务逻辑提取Contraventions
        if (enforcement.EnforcementContraventions?.Any() == true) {
            // 假设EnforcementContraventions是关联中间表,提取对应的Contravention对象
            contraventions = enforcement.EnforcementContraventions.Select(ec => ec.Contravention).ToList();
        }
        return contraventions;
    }
}

额外注意事项

  • 如果ContraventionContraventionDataView的结构差异较大,需要再为它们添加一层CreateMap<Contravention, ContraventionDataView>的规则;如果结构一致,AutoMapper会自动完成映射,无需手动配置
  • 确保你的GetContraventions方法逻辑正确,能从Enforcement的关联属性中提取到有效的Contravention集合

内容的提问来源于stack exchange,提问作者K.Z

火山引擎 最新活动