ADO.NET 使用泛型将十进制 (4,2) 转换为双精度

本文关键字:转换 双精度 NET 泛型 十进制 ADO | 更新日期: 2023-09-27 18:01:05

我正在尝试使用将字段转换为泛型类型的自定义方法将存储在 SQL Server 数据库中的十进制 (4,2( 字段转换为 C# 双精度型。(方法是 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];并获得正确的返回值,例如:06.1

数据库中失败的一些值是:0.001.006.1

我想找出导致此问题的原因并在通用方法(到目前为止适用于所有其他常见数据类型(中修复它,因为它旨在简化 ADO 并使其更易于阅读,而不是常规的可怕的"样板"ADO。

ADO.NET 使用泛型将十进制 (4,2) 转换为双精度

不能将带盒的小数转换为双精度;必须先将其转换为未装箱的小数。 您可以使用 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); 
    }
}

我敢肯定,在某些情况下这无法处理,但它应该足以让您入门。

问题是你正在双重铸造(我可能在这里没有使用正确的术语(。

reader[index]返回无法直接强制转换为doubleobject。必须先将其转换为decimal

decimal dec = 1.0M;
object obj = dec;
var x = (double)dec; //succeeds
var y = (double)obj; //fails

我不确定除了使用泛型函数获取存储在表上的值的实际类型,然后转换为要存储到的变量的类型之外,是否有解决此问题的方法。

(double)reader.Get<decimal>("My_Field"))