我有一个可空的DateTime字段"BirthDate",现有的代码是这样处理的
info.BirthDate = (DateTime?)reader["Birthdate"];
这会导致"Invalid Cast"错误并中断。好的,我理解这是因为null返回值与sql不同并且类型为"DBNull"
修复这个结果是
if (reader["Birthdate"] != DBNull.Value)
{
info.Birthdate = (DateTime)reader["Birthdate"];
}
有人能解释一下为什么这是有效的吗?我特别迷失在DBNull的。value部分。如果它是返回作为DBNull代码如何甚至达到这个块内?
DBNull
是单例。这种情况只有一次。您使用DBNull.Value
访问该实例。比较检查是否返回DBNull(.Value)
,如果没有返回(!=
),那么它知道可以安全地将其转换为DateTime
。
DBNull是一个单例类,这意味着只有这个实例类可以存在
或者您可以使用Convert.IsDBNull
方法:
if (!Convert.IsDBNull(reader["Birthdate"]))
{
info.Birthdate = (DateTime)reader["Birthdate"];
}
DBNull
是类型,而不是值。正如@aKzenT所解释的,它是作为单例实现的,这意味着该类型的实例只能有一个。获取该值的方法是通过静态.Value
属性。
这使得比较变得容易,因为任何DBNull
实例的值和对另一个DBNull
实例的引用都是相等的。
另一种更有意义的检查方法是:
int columnIndex = reader.GetOrdinal("Birthdate");
if (!reader.IsDbNull(columnIndex)) // IsDbNull should have a string overload, but it does not.
{
info.Birthdate = (DateTime)reader["Birthdate"];
}