AutoMapper映射报错:从含IEnumerable属性对象映射到IEnumerable实体
使用AutoMapper进行对象映射时,执行代码_mapper.Map<IEnumerable<SchedulerEventViewModel>>(response);(其中response为GetWorkShiftCurrentCachedResponse类型)抛出如下错误:
System.TypeLoadException: Method 'GetEnumerator' in type 'Proxy_System.Collections.Generic.IEnumerable`1[[StoreManager.Web.Areas.Turnazione.Models.SchedulerEventViewModel, StoreManager.Web, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]48512780' from assembly 'AutoMapper.Proxies, Version=0.0.0.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005' does not have an implementation.
但直接映射response的events属性:_mapper.Map<IEnumerable<SchedulerEventViewModel>>(response.events);可正常运行。现需配置正确的AutoMapper映射规则,实现直接从整个response对象映射为IEnumerable<SchedulerEventViewModel>,无需在映射时指定events属性。
类定义
public class GetWorkShiftCurrentCachedResponse { public IEnumerable<SchedulerEventCommandModel> events { get; set; } } public class SchedulerEventCommandModel { public string Title { get; set; } public string Description { get; set; } public DateTime Start { get; set; } public DateTime End { get; set; } public string RecurrenceRule { get; set; } public string RecurrenceID { get; set; } public string RecurrenceException { get; set; } public bool IsAllDay { get; set; } public int id { get; set; } public int dipendenteId { get; set; } public int idReparto { get; set; } public int idPuntoVendita { get; set; } public string stato { get; set; } } public class SchedulerEventViewModel { public string Title { get; set; } public string Description { get; set; } private DateTime start; public DateTime Start { get { return start; } set { start = value.ToUniversalTime(); } } private DateTime end; public DateTime End { get { return end; } set { end = value.ToUniversalTime(); } } public string RecurrenceRule { get; set; } public string RecurrenceID { get; set; } public string RecurrenceException { get; set; } public bool IsAllDay { get; set; } //自定义字段 public int id { get; set; } public int dipendenteId { get; set; } public int idReparto { get; set; } public int idPuntoVendita { get; set; } public string stato { get; set; } }
当前映射配置
CreateMap<SchedulerEventViewModel, SchedulerEventCommandModel>().ReverseMap(); CreateMap<GetWorkShiftCurrentCachedResponse, IEnumerable<SchedulerEventViewModel>>().ReverseMap() .ForMember(o => o.events, b => b.MapFrom(x => x)); //尝试过更明确的写法 //CreateMap<GetWorkShiftCurrentCachedResponse, IEnumerable<SchedulerEventViewModel>>().ReverseMap() // .ForMember(o => o.events, b => b.MapFrom(x => x.AsEnumerable())); //CreateMap<GetWorkShiftCurrentCachedResponse, IEnumerable<SchedulerEventViewModel>>().ReverseMap() // .ForMember(o => o.events, b => b.MapFrom(x => x.AsEnumerable<SchedulerEventViewModel>()));
AutoMapper无法直接将普通类映射到IEnumerable<T>接口,因为它无法为接口生成合法的代理实现,这就是你遇到GetEnumerator方法未实现错误的核心原因。以下是两种可行的配置方案:
方案1:使用ConvertUsing定义自定义转换逻辑
直接指定转换时的具体逻辑,明确从response中提取events并完成映射:
CreateMap<SchedulerEventViewModel, SchedulerEventCommandModel>().ReverseMap(); // 正向映射:从GetWorkShiftCurrentCachedResponse转成ViewModel集合 CreateMap<GetWorkShiftCurrentCachedResponse, IEnumerable<SchedulerEventViewModel>>() .ConvertUsing(src => _mapper.Map<IEnumerable<SchedulerEventViewModel>>(src.events)); // 反向映射:从ViewModel集合转成GetWorkShiftCurrentCachedResponse CreateMap<IEnumerable<SchedulerEventViewModel>, GetWorkShiftCurrentCachedResponse>() .ConvertUsing(src => new GetWorkShiftCurrentCachedResponse { events = _mapper.Map<IEnumerable<SchedulerEventCommandModel>>(src) });
方案2:使用MapFrom简化配置
如果不需要复杂逻辑,可直接指定映射的源属性:
CreateMap<SchedulerEventViewModel, SchedulerEventCommandModel>().ReverseMap(); // 正向映射:直接将response的events属性作为映射源 CreateMap<GetWorkShiftCurrentCachedResponse, IEnumerable<SchedulerEventViewModel>>() .MapFrom(src => src.events); // 反向映射:将集合直接赋值给response的events属性 CreateMap<IEnumerable<SchedulerEventViewModel>, GetWorkShiftCurrentCachedResponse>() .ForMember(dest => dest.events, opt => opt.MapFrom(src => src));
注意事项
- 避免直接将类映射到接口类型(如
IEnumerable<T>),AutoMapper更擅长处理具体类之间的映射,这类包装类转集合的场景需要自定义转换规则。 - 确保
SchedulerEventCommandModel与SchedulerEventViewModel之间的映射已正确配置(你当前的ReverseMap()已满足需求)。
内容的提问来源于stack exchange,提问作者pinale

