美好的一天,
IDE Visual Studio 2010
.NET 3.5
平台 WinForms
SO问题“difference between getting value from DataRow”指的是。
我有一个包含列[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");
}
}
当执行步骤并在错误的行上执行“快速监视”时,我发现通过将行更改为drSource.Field<object>("ID")
,单元格值类型为short
而不是{{1}。 1}}。当在表定义中明确地int
时,为什么会发生这种情况呢?此外,int
应隐式转换为short
,因为int
较小且应该“适合”正确吗?
答案 0 :(得分:11)
如果您的列是可以为null的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");
}
}
如果您的列是可以为null的int,并且您想要分配给可以为null的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");
}
}
答案 1 :(得分:6)
同意理查德的回答更好用,
int iID = Convert.ToInt32(drSource["ID"]);
答案 2 :(得分:5)
出于好奇,如果您自己从键/值集合中明确地投射它会发生什么?
int iID = (int)drSource["ID"];
答案 3 :(得分:4)
根据Field扩展的实现,您的字段具有DbNull值。
public static T Field<T>(this DataRow row, string columnName)
{
DataSetUtil.CheckArgumentNull<DataRow>(row, "row");
return UnboxT<T>.Unbox(row[columnName]);
}
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;
}
}
答案 4 :(得分:1)
将行值转换为int变量的另一种方法是使用'object'并将其转换为Int32,如下所示:
int iID = Convert.ToInt32(row.Field<object>("ID"));