AutoMapper自定义类型转换器无法编译及使用问题
解决AutoMapper自定义类型转换器编译错误及映射问题
错误原因分析
- 泛型类型不匹配:你的转换器实现的是
ITypeConverter<TPWorkPlanDTO, IEnumerable<WorkingTime>>,但映射配置的目标类型是List<WorkingTime>。AutoMapper要求自定义转换器的目标类型必须与映射配置的目标类型严格匹配,二者不存在隐式转换关系,因此触发编译报错。 - 类型转换逻辑错误:原转换器中直接将
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
相关产品推荐
相关产品推荐

