我对C#还是很陌生,所以请多多包涵。我有一个带有如下表的Access数据库:
ID1 ID2 Name
----------------------
1111 1234567 Joe
2222 1234567 Patricia
3333 7654321 Laurie
没有一个字段包含空值。我正在尝试将每个列的值的最长文本表示形式的长度存储在
DataTable
中。根据rein对this similar question的回答,我包括了这个方便的泛型函数:
public static T ConvertFromDBVal<T>(object obj)
{
if (obj == null || Convert.IsDBNull(obj))
return default(T);
else
return (T)obj;
}
我从表中获取数据如下:
public DataTable GetMetadata(string tableName)
{
...
// My OLEDB connection _oleConnection is already open
OleDbCommand selectTable = new OleDbCommand("SELECT * FROM [" +
tableName + "]", _oleConnection);
OleDbDataReader oleReader = selectTable.ExecuteReader();
DataTable schemaTable = oleReader.GetSchemaTable().Copy();
schemaTable.Columns.Add("_maxCharLength", typeof(int));
foreach (DataRow schemaRow in schemaTable.Rows)
{
OleDbCommand getMax = new OleDbCommand();
getMax.Connection = _oleConnection;
// Convert non-text fields to strings before getting lengths
if (schemaRow.Field<Type>("DataType") == typeof(string))
{
getMax.CommandText = "SELECT MAX(LEN(" +
schemaRow.Field<string>("ColumnName") + ")) FROM " +
tableName;
}
else
{
getMax.CommandText = "SELECT MAX(LEN(STR(" +
schemaRow.Field<string>("ColumnName") + "))) FROM " +
tableName;
}
int maxCharLength = ConvertFromDBVal<int>(getMax.ExecuteScalar());
schemaRow.SetField(schemaRow.Field<int>("_maxCharLength"),
maxCharLength);
getMax.Dispose();
getMax = null;
}
...
return schemaTable;
}
调试器对
schemaRow.SetField(...)
感到生气,并说:Cannot cast DBNull.Value to type 'System.Int32'. Please use a nullable type.
所以我尝试使用可为空的类型。我更换了
schemaTable.Columns.Add("_maxCharLength", typeof(int?)); // was typeof(int)
然后调试器说
DataSet does not support System.Nullable<>.
所以我将其更改回
int
。即使我使用该函数转换了任何空值,我仍然在foreach
循环中检查了值及其类型,如下所示:Console.WriteLine("{0}, {1}, {2}, {3}",
tableName,
schemaRow.Field<string>("ColumnName"),
maxCharLength,
maxCharLength.GetType());
这完全没有问题。我在控制台中得到以下内容:
Table1, ID1, 4, System.Int32
Table1, ID2, 7, System.Int32
Table1, Name, 8, System.Int32
没有空值,没有异常,一切都与我期望的一样。那为什么
SetField
不让我将这些值放在DataTable
中? 最佳答案
我认为您需要将SetField的行更改为
schemaRow.SetField("_maxCharLength", maxCharLength);
DataRow.SetField扩展名的第一个参数要求列的名称,或列在列集合或DataColumn实例内的顺序位置。
该错误消息是由于您尝试使用
maxCharLength
扩展名读取_ DataRow.Field<T>
字段的值而引起的。但是,此时代码的_maxCharLength
字段仍为null,因为您尚未为其设置任何值。编译器无法警告您有关此错误的信息,因为从逻辑的角度来看,您正在调用SetField扩展的有效重载。需要整数来表示要为其设置值的列的顺序位置的列。
关于c# - SetField无法将DBNull.Value强制转换为System.Int32,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22843154/