Automapper 2.2.1.0版本AutoMapperMappingException异常求助
首先,针对你遇到的偶发AutoMapperMappingException,结合你使用的是非常老旧的AutoMapper 2.2.1.0版本,我梳理几个最可能的原因和对应的解决方案:
1. 优先定位具体失败点:查看InnerException
偶发异常最头疼的是无法稳定复现,但AutoMapperMappingException的InnerException会告诉你具体是哪个属性映射失败,这是定位问题的关键。建议在catch块中记录这个内部异常:
try { var sqlrdr = _helper.GetReaderByCmdWithParameter(spName, para); varObj = Mapper.Map<IDataReader, List<AgriAdvisor>>(sqlrdr); } catch (AutoMapperMappingException ex) { // 务必记录InnerException的详细信息,包括堆栈和错误消息 // 比如用日志框架输出:logger.Error(ex.InnerException, "AutoMapper映射失败"); throw; // 保持原有异常抛出,或者根据业务处理 }
绝大多数情况下,内部异常会提示“无法将DBNull转换为XX类型”这类信息,指向具体的属性转换问题。
2. 处理NULL值到值类型的映射问题
AutoMapper 2.x版本对IDataReader映射的NULL值处理不够智能,如果你的AgriAdvisor实体中有值类型属性(比如int、DateTime、decimal),而数据库返回的对应字段偶尔为NULL,就会触发转换异常。
解决方法是在映射配置中显式处理NULL情况:
// 全局配置AgriAdvisor的映射 Mapper.CreateMap<IDataReader, AgriAdvisor>() // 示例:处理int类型的NULL,默认值设为0或其他业务允许的默认值 .ForMember(dest => dest.Age, opt => opt.MapFrom(src => src.IsDBNull(src.GetOrdinal("Age")) ? 0 : src.GetInt32(src.GetOrdinal("Age")))) // 示例:处理DateTime类型的NULL,默认值设为DateTime.MinValue或业务默认值 .ForMember(dest => dest.CreateTime, opt => opt.MapFrom(src => src.IsDBNull(src.GetOrdinal("CreateTime")) ? DateTime.MinValue : src.GetDateTime(src.GetOrdinal("CreateTime"))));
3. 确保DataReader的生命周期正确管理
偶发异常也可能是DataReader被提前关闭导致的——比如你的SqlHelper没有正确使用using语句包裹数据库连接、命令或DataReader,在高并发的生产环境中,资源被提前释放,导致AutoMapper读取DataReader时出错。
修改代码,用using确保DataReader在映射完成前保持打开:
Sqlhelper _helper = new Sqlhelper(ObjConnection); List<AgriAdvisor> varObj = null; try { using (var sqlrdr = _helper.GetReaderByCmdWithParameter(spName, para)) { varObj = Mapper.Map<IDataReader, List<AgriAdvisor>>(sqlrdr); } } catch (Exception ex) { // 日志记录 }
同时检查SqlHelper内部的实现,确保GetReaderByCmdWithParameter返回的DataReader对应的数据库连接没有被提前关闭(比如不要在方法内部用using包裹Connection,除非用CommandBehavior.CloseConnection)。
4. 考虑升级AutoMapper版本
AutoMapper 2.2.1.0是2012年的版本,距今已经非常久远,后续的版本(比如4.x、6.x、10+)修复了大量IDataReader映射的bug,包括线程安全、NULL处理、字段匹配等问题。如果业务允许,升级到较新的稳定版本(比如最新的LTS版本)可以从根源上避免很多老版本的遗留问题。
内容的提问来源于stack exchange,提问作者ABD

