Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ADO.NET使用泛型将十进制(4,2)转换为双精度_C#_Sql_Sql Server_Sql Server 2008_Ado.net - Fatal编程技术网

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

C# ADO.NET使用泛型将十进制(4,2)转换为双精度,c#,sql,sql-server,sql-server-2008,ado.net,C#,Sql,Sql Server,Sql Server 2008,Ado.net,我正在尝试使用一种将字段转换为泛型类型的自定义方法,将存储在SQL Server数据库中的十进制(4,2)字段转换为C#double。(方法是SqlDataReader类的扩展。) 当我运行代码时,我不断得到错误“指定的强制转换无效” 方法如下: public static T Get<T>(this SqlDataReader reader, string field) { try { int index = reader.GetOrdinal(field

我正在尝试使用一种将字段转换为泛型类型的自定义方法,将存储在SQL Server数据库中的十进制(4,2)字段转换为C#double。(方法是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); 
    }
}
publicstatict-Get(此SqlDataReader,字符串字段)
{
试一试{
int index=reader.GetOrdinal(字段);
if(reader.IsDBNull(index))返回默认值(T);
T项=(T)读取器[索引];
退货项目;
}捕获(例外e){
控制台写入线(e);
返回默认值(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"));
//reader是一个具有打开连接的SqlDataReader实例,以及通过“Read()”方法获取的字段。
MyClass myObject=newMyClass(reader.Get(“My_字段”);
SqlDataReader中包含正确的数据。
index
变量设置为正确的字段序号,在调试时,我可以运行行
读取器[1]
并获得适当的返回值,如:
0
6.1

对此失败的数据库中的一些值是:
0.00
1.00
6.1


我想找出导致此问题的原因,并在泛型方法中解决它(到目前为止,泛型方法适用于所有其他常见的数据类型),因为它旨在简化ADO并使其更易于阅读,而不是常规的糟糕透顶的“锅炉板”ADO。

问题在于您是在重复铸造(我在这里使用的术语可能不正确)

reader[index]
返回一个
对象
,该对象不能直接转换为
double
。它必须先转换为
十进制

decimal dec = 1.0M;
object obj = dec;

var x = (double)dec; //succeeds
var y = (double)obj; //fails
我不确定除了使用泛型函数获取存储在表中的值的实际类型,然后转换为要存储它的变量类型之外,是否还有其他方法可以解决这个问题

(double)reader.Get<decimal>("My_Field"))
(双)reader.Get(“我的_字段”))

不能将盒装小数转换为双精度小数;您必须先将其转换为非固定小数。您可以使用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); 
    }
}
publicstatict-Get(此SqlDataReader,字符串字段)
{
试一试{
int index=reader.GetOrdinal(字段);
if(reader.IsDBNull(index))返回默认值(T);
对象项=读取器[索引];
返回项为T?(T)项:(T)转换.ChangeType(项,typeof(T));
}捕获(例外e){
控制台写入线(e);
返回默认值(T);
}
}

我确信有些情况下这不能解决,但应该足以让你开始。

你所说的失败是什么意思?如果有异常,则应提供异常。对于
DataRow
已是具有相同想法的扩展方法,异常错误为:“指定的强制转换无效”。我没有在任何地方写“归档”?是的,我使用了行
(double)reader.Get(“我的字段”)
作为临时修复。理想情况下,我想永久性地解决它,但正如@Fabio所说,我的简单泛型方法已经过时了……我认为这是不对的<代码>对象o=10;十进制d=(十进制)o使用此代码,我得到相同的结果error@gmailuser这是因为您的o包含一个对装箱整数的引用,不能直接转换为十进制。必须先把它拆开。很好,似乎对我所有的测试都有效。当然,总会有一些离题的案例,但我必须在它们出现时处理它们。谢谢@LoganDangerBlack我想到了这段代码的一个重要潜在问题(这实际上是从DataReader读取数据的过程中固有的):如果数字列中有一个DbNull,这段代码会将其转换为零。因此,最好将该方法调用为
reader.Get(“My_字段”)
Good catch。我在大多数有意义的地方使用可空包装器。(其中我的数据库将允许空值。)