Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何从数据库中获取可为Null的DateTime_C#_Sql Server_Datetime_Nullable_Sqldatareader - Fatal编程技术网

C# 如何从数据库中获取可为Null的DateTime

C# 如何从数据库中获取可为Null的DateTime,c#,sql-server,datetime,nullable,sqldatareader,C#,Sql Server,Datetime,Nullable,Sqldatareader,我的SQL Server数据库包含可为空的日期时间值。如何在C#中的应用程序中将它们转换为可为空的DateTime对象 这是我认为的样子,但事实并非如此: DateTime? dt = (DateTime?) sqldatareader[0]; SQL null与.NET null不同;您必须与System.DBNull.Value进行比较: object sqlDateTime = sqldatareader[0]; DateTime? dt = (sqlDateTime == System

我的SQL Server数据库包含可为空的日期时间值。如何在C#中的应用程序中将它们转换为可为空的DateTime对象

这是我认为的样子,但事实并非如此:

DateTime? dt = (DateTime?) sqldatareader[0];

SQL null与.NET null不同;您必须与System.DBNull.Value进行比较:

object sqlDateTime = sqldatareader[0];
DateTime? dt = (sqlDateTime == System.DBNull.Value)
    ? (DateTime?)null
    : Convert.ToDateTime(sqlDateTime);
在回答您的评论时,
DataReader
Item
属性的数据类型是基础数据库类型的数据类型。对于非空SQL Server数据库,它可以是
System.Data.SqlTypes.SqlDateTime
,对于空列,它可以是
System.DBNull
,对于Odbc数据库,它可以是
System.Data.Odbc.OdbcTypes.SmallDateTime
,或者几乎任何东西。唯一可以依赖的是它的类型是
object

这也是为什么我建议使用
Convert.ToDateTime()
而不是将类型强制转换为
DateTime
。不能保证ODBC或任何日期列可以强制为.NET
DateTime
。我注意到您的评论指定了一个“sqldatareader”,SQL Server
System.Data.SqlTypes.SqlDateTime
确实可以强制为
System.DateTime
,但您最初的问题并没有告诉我们这一点


有关使用
DataReader
s的更多信息,请参阅。

您需要检查值是否为“DBNull”,而不仅仅是null。我在我的博客上发布了一个小助手类:

一旦实现了该类,您就可以这样使用它:

DateTime? dt = DBConvert.To<datetime?>(sqldatareader[0]);
DateTime?dt=DBConvert.To(sqldatareader[0]);

不久前,我为数据行编写了一系列扩展方法来进行这种向下转换……因为我讨厌写重复的废话。用法很简单:

foreach( DataRow dr in someDataTable )
{
  DateTime? dt = dr.CastAsDateTimeNullable( "lastUpdated" ) ;
  int       id = dr.CastAsInt( "transactionID" ) ;
  // etc.
}
这里是关于日期时间值的部分。为其他数据类型添加实现应该非常简单。如果有人这么想,对数据阅读器做同样的事情并不困难

我试图提出泛型方法,但泛型方法的局限性使得它很难或不可能实现,并且仍然可以获得我想要的行为(例如,
null
值,而不是
default(T)
-获取SQL空值的默认值将使区分
0
null
变得困难)


我最近发现了这个技巧,很简单:

DateTime? dt = sqldatareader[0] as DateTime?;
只需使用:

System.Nullable<System.DateTime> yourVariableName;
System.Nullable yourVariableName;

让自己变得简单:)

创建助手方法怎么样

private static DateTime? MyDateConverter(object o)
{
    return (o == DBNull.Value || o == null) ? (DateTime?)null : Convert.ToDateTime(o);
}
用法


它怎么不起作用?有例外吗?请不要在标题前加标签。有标签是有原因的。这和数据库有什么关系?非常精确的解决方案!从现在起,我将使用这个方法,而不是更麻烦的三元法。你能解释一下吗?我不明白DateTime后面有什么以及为什么有“?”。@MDB只是表示它是一个可为空的DateTime
System.Nullable<System.DateTime> yourVariableName;
private static DateTime? MyDateConverter(object o)
{
    return (o == DBNull.Value || o == null) ? (DateTime?)null : Convert.ToDateTime(o);
}
MyDateConverter(sqldatareader[0])