AutoMapper映射IDataReader到Money类时float属性转换无效如何解决
问题根因
SQL Server的float类型数据通过IDataReader读取时,默认返回的是.NET的double(双精度浮点)类型的装箱对象。AutoMapper的DataReader映射逻辑默认会直接对值进行拆箱赋值,而double类型无法直接拆箱为C#的float(Single单精度浮点)类型,因此触发「指定的转换无效」异常。
你之前的自定义配置未生效的原因是,你将字段值转为了double类型,目标属性仍是float,还是需要走自动类型转换逻辑,并未解决拆箱类型不匹配的问题。
解决方案
方案1:修正单字段映射配置
直接将读取到的字段值转换为和目标属性匹配的float类型即可,示例如下:
cfg.CreateMap<IDataReader, Money>() .ForMember(x => x.Amount, opt => opt.MapFrom(rdr => Convert.ToSingle(rdr["Amount"]))) // 另一个float属性也按相同规则配置 .ForMember(x => x.OtherFloatProp, opt => opt.MapFrom(rdr => Convert.ToSingle(rdr["OtherFloatColumn"])));
方案2:配置全局类型转换规则
如果有大量需要从double转float的映射场景,可以新增全局类型转换规则,不需要逐个字段配置:
IMapper DataReaderMapper = new MapperConfiguration(cfg => { cfg.AddDataReaderMapping(); // 新增全局double转float的转换规则 cfg.CreateMap<double, float>().ConvertUsing(d => (float)d); // 原有其他映射配置保持不变 cfg.CreateMap<IDataReader, MyApp>(); cfg.CreateMap<IDataReader, MyRole>(); cfg.CreateMap<IDataReader, MyBill>(); cfg.CreateMap<IDataReader, Money>(); }).CreateMapper();
方案3:优化属性类型(推荐)
从业务合理性出发,金额类字段不推荐使用浮点类型存储,避免精度丢失问题:
- 如果可以修改DTO定义,建议将
Money类的Amount属性类型改为decimal,和SQL Server的decimal/money类型适配,完全规避精度问题 - 若必须使用浮点类型,建议改为
double类型,和SQL Server的float类型原生匹配,无需额外转换配置
内容的提问来源于stack exchange,提问作者Matt W
相关产品推荐
相关产品推荐

