OleDb和C#之间使用泛型方法的无效转换问题

时间:2017-12-27 07:34:30

标签: c# .net generics casting oledb

当我迭代一个作为OleDb GetOleDbSchemaTable输出的DataTable.Rows集合时,我得到“指定的强制转换无效”错误。我正在查询OleDbSchemaGuid.Columns行集,它返回有关基础MS Access数据库表中列的架构信息。

我知道OleDb数据类型和C#数据类型之间存在差异,并且DBNull对于C#值类型是无效的,所以我想要做的是使用泛型方法:

  1. 检查DBNull并将其替换为类型
  2. 的默认值
  3. 将对象从数据库中取消装入其ADO类型
  4. 然后,我将在方法之外将ADO类型转换为C#类型。

    我尝试过的解决方案只能使用字符串。我也需要它来处理值类型。

    如果它很重要,我正在查询OleDbSchemaGuid.Columns架构,如下所示:

    dbConnection.Open ( );
    DataTable dt = dbConnection.GetOleDbSchemaTable ( OleDbSchemaGuid.Columns ,
                            new Object[ ] { null , null , "SomeTableName" , null });
    

    我正在尝试填充ORDINAL_POSITION变量,该变量位于Row的ItemArray的第6个索引位置。根据MS文档,此列的类型为:

    OLE DB类型是DBTYPE_UI4。 ADO类型是adUnsignedInt。 .NET框架类型是UInt32。所以我希望这意味着C#类型是uint。

    我正在迭代行并从它的字段中填充变量,如下所示:

    for ( int i = 0 ; i < dt.Rows.Count - 1 ; i++ ) 
    {                       
        uint ORDINAL_POSITION = dh.NullToDefault<uint> ( dt.Rows[i].ItemArray[6]);               
    }
    

    NullToDefault是我编写的一个通用方法,用于解决我遇到的第一个问题,即DBNull值的存在,这是SQL Developer的一个新手错误。它应该返回数据库列中的值或C#类型的默认值。

    这是NullToDefault:

    public T NullToDefault<T> ( T value )
            {
                if ( !Convert.IsDBNull ( value ) )
                {
                    return ( T ) Convert.ChangeType ( value , typeof ( T ) );
                }
                else
                {
                    return default ( T );   //returns the default for the type... not null
                }
            }
    

    我在方法中设置了一个断点,当我执行上面的代码来填充ORDINAL_POSITION时,Intellesence显示= 0,obj = 4,我得到:

    An unhandled exception of type 'System.InvalidCastException' occurred in SomeProgram.exe
    Specified cast is not valid.
    

    我可以在非泛型方法中转换上述值,如下所示:

    public Int32 GetInt32 ( object obj )
    {
        if ( obj == DBNull.Value ) return 0;
        return Convert.ToInt32 ( obj );
    }
    

    到目前为止,我无法用通用的方法做到这一点。

    编辑:我从下面的评论中了解到,我的泛型方法包含了一个隐式转换,它在Type Object中无效,因此我的原始泛型方法已经更新。

0 个答案:

没有答案