You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AutoMapper自定义类型转换器无法编译及使用问题

解决AutoMapper自定义类型转换器编译错误及映射问题

错误原因分析

  1. 泛型类型不匹配:你的转换器实现的是ITypeConverter<TPWorkPlanDTO, IEnumerable<WorkingTime>>,但映射配置的目标类型是List<WorkingTime>。AutoMapper要求自定义转换器的目标类型必须与映射配置的目标类型严格匹配,二者不存在隐式转换关系,因此触发编译报错。
  2. 类型转换逻辑错误:原转换器中直接将TPWorkingTimeDTO集合强制转换为WorkingTime集合,这两个类型无继承关系,强制转换会导致运行时异常,必须通过AutoMapper完成单个DTO到模型的映射。

解决方案

步骤1:配置单个DTO到模型的映射

首先定义TPWorkingTimeDTO到WorkingTime的属性映射,处理命名差异:

CreateMap<TPWorkPlanDTO.TPWorkingTimeDTO, WorkingTime>()
    .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.worktime_id))
    .ForMember(dest => dest.StartTime, opt => opt.MapFrom(src => src.start_time))
    .ForMember(dest => dest.EndTime, opt => opt.MapFrom(src => src.end_time));

方案A:调整转换器适配List目标类型

修改转换器,使其实现ITypeConverter<TPWorkPlanDTO, List<WorkingTime>>,并注入IMapper完成单个对象映射:

public class WorkPlanToWorkingTimeListConverter : ITypeConverter<TPWorkPlanDTO, List<WorkingTime>>
{
    private readonly IMapper _mapper;

    public WorkPlanToWorkingTimeListConverter(IMapper mapper)
    {
        _mapper = mapper;
    }

    public List<WorkingTime> Convert(TPWorkPlanDTO source, List<WorkingTime> destination, ResolutionContext context)
    {
        if (source == null)
        {
            return new List<WorkingTime>();
        }

        // 空值安全遍历并映射每个TPWorkingTimeDTO到WorkingTime
        return source.Weeks?
            .SelectMany(week => week.Days?
                .SelectMany(day => day.Shifts?
                    .Select(shift => _mapper.Map<WorkingTime>(shift))))
            .ToList() ?? new List<WorkingTime>();
    }
}

对应的映射配置:

CreateMap<TPWorkPlanDTO, List<WorkingTime>>()
    .ConvertUsing<WorkPlanToWorkingTimeListConverter>();

方案B:保持转换器返回IEnumerable

如果希望转换器更通用,可保持其返回IEnumerable<WorkingTime>,映射配置目标类型同步调整:

public class WorkPlanToWorkingTimeListConverter : ITypeConverter<TPWorkPlanDTO, IEnumerable<WorkingTime>>
{
    private readonly IMapper _mapper;

    public WorkPlanToWorkingTimeListConverter(IMapper mapper)
    {
        _mapper = mapper;
    }

    public IEnumerable<WorkingTime> Convert(TPWorkPlanDTO source, IEnumerable<WorkingTime> destination, ResolutionContext context)
    {
        if (source == null)
        {
            return Enumerable.Empty<WorkingTime>();
        }

        return source.Weeks?
            .SelectMany(week => week.Days?
                .SelectMany(day => day.Shifts?
                    .Select(shift => _mapper.Map<WorkingTime>(shift)))) ?? Enumerable.Empty<WorkingTime>();
    }
}

映射配置:

CreateMap<TPWorkPlanDTO, IEnumerable<WorkingTime>>()
    .ConvertUsing<WorkPlanToWorkingTimeListConverter>();

使用时若需要List,直接调用ToList():

var workingTimeList = _mapper.Map<IEnumerable<WorkingTime>>(workPlanDto).ToList();

内容的提问来源于stack exchange,提问作者Matt Baech

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 00:40:56