转换为可空double列表出错:PostgreSQL DOUBLE PRECISION字段处理问题
这个问题我之前处理过好几次,直接用(double?)dt["abb_conv"]强制转换之所以报错,核心原因有两个:一是PostgreSQL返回的NULL值在DataTable里会被存为DBNull.Value,而不是C#里的null,直接强制转换会失败;二是PostgreSQL的DOUBLE PRECISION字段有时候会被ADO.NET映射为decimal类型,而非double,直接转double?也会触发类型转换错误。
下面给你几个实用的解决办法:
方法一:手动判断DBNull并转换(兼容所有场景)
先检查字段值是否为DBNull.Value,是则直接添加null,否则用Convert.ToDouble做类型转换——它能自动处理decimal等其他可转换的数值类型:var fieldValue = dt["abb_conv"]; _powerConv.abb_conv.Add(fieldValue == DBNull.Value ? null : (double?)Convert.ToDouble(fieldValue));方法二:使用DataRow的Field
扩展方法(推荐,代码更简洁)
如果你引用了System.Data.DataSetExtensions程序集,可以用Field<T>方法,它内部已经封装了DBNull到null的转换逻辑,专门用来处理nullable类型:_powerConv.abb_conv.Add(dt.Field<double?>("abb_conv"));注意:如果你的项目里没有这个扩展方法,需要在NuGet安装
System.Data.DataSetExtensions包,或者手动添加对该程序集的引用。方法三:排查并匹配实际返回类型
如果上面两种方法还是报错,建议先打印字段的实际类型,确认ADO.NET到底把PostgreSQL的DOUBLE PRECISION映射成了什么:Console.WriteLine(dt["abb_conv"].GetType().FullName);比如如果实际是
decimal类型,可以针对性地转换:var fieldValue = dt["abb_conv"]; _powerConv.abb_conv.Add(fieldValue == DBNull.Value ? null : (double?)(decimal)fieldValue);
一般来说,方法二是最省心的,代码简洁且不容易出错,优先推荐使用。
内容的提问来源于stack exchange,提问作者papagallo

