Oracle.DataAccess DataRow.Field <decimal> InvalidCastException

Vác*_*arý 8 c# oracle

在我的代码中,我System.Data.OracleClient用于ora数据库连接.我想替换这个库(因为它已经过时了)Oracle.DataAccess.不幸的是我发现DataRow.Field()抛出InvalidCastException.同样的行为是(decimal)x.Rows[0]["COLUME_NAME"].我没有这个问题System.Data.OracleClient.

这是代码示例

using (var oracleConnection = new OracleConnection(connectionString))
{
    using (var command = new OracleCommand("select * from tr", oracleConnection))
    {
        var result = new DataTable();
        var adapter = new OracleDataAdapter(command);
        adapter.Fill(result);
        Console.WriteLine(result.Rows[0].Field<decimal>("TR_SEQ_NUM"));
        //Console.WriteLine((decimal)result.Rows[0]["TR_SEQ_NUM"]);
    }
}
Run Code Online (Sandbox Code Playgroud)

TR_SEQ_NUM具有NUMBER(8,0)数据类型,完整异常为:

System.InvalidCastException: Specified cast is not valid.
   at System.Data.DataRowExtensions.UnboxT`1.ValueField(Object value)
Run Code Online (Sandbox Code Playgroud)

代码示例使用System.Data.OracleClient但不使用Oracle.DataAccess

我知道我可以使用,Convert.ChangeType但我想知道是否有某种方式可以使用相同的行为System.Data.OracleClient.重构我的所有代码将花费太多时间.

小智 2

数据库中的值不是小数,并且装箱的 int(错误消息中的“value”参数)无法转换为小数,尽管可以将 int 转换为小数。这个答案会带来更多信息

您可以通过以下方式查看它的实际效果:

void Main()
{
    int anInt = 5;
    object boxedInt = (object)anInt;
    decimal unboxed = Convert.ToDecimal(boxedInt); //5
    decimal unboxed2 = (decimal)boxedInt; //InvalidCastException
}
Run Code Online (Sandbox Code Playgroud)

如果您查看 Unbox.ValueField 方法,它确实...

  private static T ValueField(object value)
  {
    if (DBNull.Value == value)
      throw DataSetUtil.InvalidCast(Strings.DataSetLinq_NonNullableCast((object) typeof (T).ToString()));
    return (T) value;
  }
Run Code Online (Sandbox Code Playgroud)

基本上你需要

Convert.ToDecimal(rows[0]["TR_SEQ_NUM"]); 
Run Code Online (Sandbox Code Playgroud)