C# DataRow.Field<T>(string Column) 抛出无效的强制转换异常
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9885601/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
DataRow.Field<T>(string Column) throws invalid cast exception
提问by that0th3rGuy
Good day,
再会,
IDEVisual Studio 2010
.NET3.5
PlatformWinForms
IDEVisual Studio 2010
.NET3.5
平台WinForms
The SO question " difference between getting value from DataRow" refers.
SO 问题“从 DataRow 获取价值之间的差异”是指。
I have a database table with a column [ID] INT IDENTITY(1, 1) NOT NULL PRIMARY KEY. When querying this table and storing the values in local variables I get an invalid cast exception; sample code:
我有一个带有列的数据库表[ID] INT IDENTITY(1, 1) NOT NULL PRIMARY KEY。当查询这个表并将值存储在局部变量中时,我得到一个无效的强制转换异常;示例代码:
string sQuery = @"
SELECT [ID], [Description]
FROM [Sources]
ORDER BY [Description] ";
using (DataTable dtSources = SQLHelper.Fetch(sQuery))
{
foreach (DataRow drSource in dtSources.Rows)
{
int iID = drSource.Field<int>("ID"); // InvalidCastException
string sDescrption = drSource.Field<string>("Description");
}
}
When stepping the execution and performing a "Quick Watch" on the faulty line I discovered that, by changing the line to drSource.Field<object>("ID"), the cell value type is that of shortand not of int. Why would this happen when, in the table definition, this is clearly and int? Furthermore, shortshould be implicitly converted to intsince shortis smaller and should "fit" right?
当逐步执行并在故障行上执行“快速观察”时,我发现,通过将行更改为drSource.Field<object>("ID"),单元格值类型是 ofshort而不是int。为什么会发生这种情况,在表定义中,这显然是 and int?此外,short应该隐式转换为int因为short更小并且应该“适合”对吗?
采纳答案by Richard
Out of curiosity, what happens if you explicitly cast it yourself from the key/value collection?
出于好奇,如果您自己从键/值集合中显式地转换会发生什么?
int iID = (int)drSource["ID"];
回答by Sergey Berezovskiy
According to implementation of Field extension, your field has DbNull value.
根据 Field 扩展的实现,您的字段具有 DbNull 值。
public static T Field<T>(this DataRow row, string columnName)
{
DataSetUtil.CheckArgumentNull<DataRow>(row, "row");
return UnboxT<T>.Unbox(row[columnName]);
}
UnboxT is a private class that provides methods for converting object to T. In your case ValueField converter is used:
UnboxT 是一个私有类,提供将对象转换为 T 的方法。在您的情况下,使用 ValueField 转换器:
private static class UnboxT<T>
{
internal static readonly Converter<object, T> Unbox;
static UnboxT()
{
DataRowExtensions.UnboxT<T>.Unbox =
new Converter<object, T>(DataRowExtensions.UnboxT<T>.ValueField);
}
private static T ValueField(object value)
{
if (DBNull.Value == value)
{
// You get this exception
throw DataSetUtil.InvalidCast(Strings.DataSetLinq_NonNullableCast(typeof(T).ToString()));
}
return (T) value;
}
}
回答by Karen
If your column is a nullable int, but you are trying to assign to an int, with a default value of 0 :
如果您的列是一个可为空的 int,但您尝试分配给一个 int,默认值为 0 :
using (DataTable dtSources = SQLHelper.Fetch(sQuery))
{
foreach (DataRow drSource in dtSources.Rows)'
{
int iID = drSource.Field<int?>("ID") ?? 0;
string sDescrption = drSource.Field<string>("Description");
}
}
If your column is a nullable int, and you want to assign to a nullable int :
如果您的列是一个可为空的 int,并且您想分配给一个可为空的 int :
using (DataTable dtSources = SQLHelper.Fetch(sQuery))
{
foreach (DataRow drSource in dtSources.Rows)
{
int? iID = drSource.Field<int?>("ID");
string sDescrption = drSource.Field<string>("Description");
}
}
回答by Himalaya Garg
Agree with Richard's answer just better to use,
同意理查德的回答,更好地使用,
int iID = Convert.ToInt32(drSource["ID"]);
回答by Kendon Darlington
Another way to get your row value into an int variable is to use 'object' and convert it to Int32 like so:
将行值放入 int 变量的另一种方法是使用 'object' 并将其转换为 Int32,如下所示:
int iID = Convert.ToInt32(row.Field<object>("ID"));
int iID = Convert.ToInt32(row.Field<object>("ID"));

