当我迭代一个作为OleDb GetOleDbSchemaTable输出的DataTable.Rows集合时,我得到“指定的强制转换无效”错误。我正在查询OleDbSchemaGuid.Columns行集,它返回有关基础MS Access数据库表中列的架构信息。
我知道OleDb数据类型和C#数据类型之间存在差异,并且DBNull对于C#值类型是无效的,所以我想要做的是使用泛型方法:
然后,我将在方法之外将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中无效,因此我的原始泛型方法已经更新。