我正在尝试使用将字段转换为泛型类型的自定义方法将存储在SQL Server数据库中的十进制(4,2)字段转换为C#double。 (Method是SqlDataReader类的扩展。)
当我运行代码时,我不断收到错误“指定的强制转换无效”。
以下是方法:
public static T Get<T>(this SqlDataReader reader, string field)
{
try {
int index = reader.GetOrdinal(field);
if (reader.IsDBNull(index)) return default(T);
T item = (T)reader[index];
return item;
} catch (Exception e) {
Console.WriteLine(e);
return default(T);
}
}
在我调用方法的地方,我正在将值读入类构造函数中,如:
// reader is a SqlDataReader instance with an open connection, and fields obtained via the 'Read()' method.
MyClass myObject = new MyClass(reader.Get<double>("My_Field"));
SqlDataReader中包含正确的数据。 index
变量设置为正确的字段序号,在调试时我可以运行行reader[1];
并获得正确的返回值,如:0
或6.1
。
数据库失败的一些值是:0.00
,1.00
,6.1
。
我想找出造成这个问题的原因,并在通用方法(迄今为止适用于所有其他常见数据类型)中修复它,因为它旨在简化ADO并使其更易于阅读,而不是常规的上帝可怕的“锅炉板”ADO。
答案 0 :(得分:2)
您无法将盒装小数转换为double;你必须先将其转换为未装箱的小数。您可以使用Convert类来执行您尝试执行的操作:
public static T Get<T>(this SqlDataReader reader, string field)
{
try {
int index = reader.GetOrdinal(field);
if (reader.IsDBNull(index)) return default(T);
object item = reader[index];
return item is T ? (T)item : (T)Convert.ChangeType(item, typeof(T));
} catch (Exception e) {
Console.WriteLine(e);
return default(T);
}
}
我确定在某些情况下这无法处理,但它应该足以让你开始。
答案 1 :(得分:1)
问题在于你是否进行了双重拼接(我可能没有在这里使用正确的术语)。
reader[index]
会返回object
,而double
无法直接投放到decimal
。必须先将其转换为decimal dec = 1.0M;
object obj = dec;
var x = (double)dec; //succeeds
var y = (double)obj; //fails
。
(double)reader.Get<decimal>("My_Field"))
我不确定是否有解决此问题的方法,除了使用通用函数获取存储在表中的值的实际类型,然后转换为要存储的变量的类型进入。
{{1}}