如何从数据库中获取可以为空的DateTime
我的SQL Server数据库包含可空的DateTime值。 如何在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.DBNull
,或空列的System.Data.Odbc.OdbcTypes.SmallDateTime
,或ODBC数据库的System.Data.Odbc.OdbcTypes.SmallDateTime
,或者几乎任何东西。 你唯一可以依赖的是它是object
类型。
这也是我建议使用Convert.ToDateTime()
而不是类型强制到DateTime
。 无法保证可以将ODBC或任何日期列强制转换为.NET DateTime
。 我注意到你的注释指定了一个“sqldatareader”,并且SQL Server System.Data.SqlTypes.SqlDateTime
确实可以被强制转换为System.DateTime
,但你原来的问题没有告诉我们。
有关使用DataReader
的更多信息,请参阅MSDN 。
我最近发现了这个技巧,很简单:
DateTime? dt = sqldatareader[0] as DateTime?;
您需要检查值“是否为DBNull”而不是null。 我在我的博客上发布了一个小帮手类: http : //improve.dk/archive/2007/10/08/handling-dbnulls.aspx
实现该类后,您可以像这样使用它:
DateTime? dt = DBConvert.To(sqldatareader[0]);
不久之前,我为DataRow写了一堆扩展方法来做这种向下转换…因为我不喜欢写重复的文件。 用法很简单:
foreach( DataRow dr in someDataTable ) { DateTime? dt = dr.CastAsDateTimeNullable( "lastUpdated" ) ; int id = dr.CastAsInt( "transactionID" ) ; // etc. }
这是DateTime值的部分。 为其他数据类型添加实现应该是非常简单的。 如果人们如此倾向于对DataReader做同样的事情并不困难。
我尝试提出generics方法,但是generics方式的限制使得很难或不可能做到并且仍然得到我想要的行为(例如, null
值而不是default(T)
– 获取SQL NULL的默认值会区分0
和null
…很难)。
public static class DataRowExtensions { #region downcast to DateTime public static DateTime CastAsDateTime( this DataRow row , int index ) { return toDateTime( row[index] ) ; } public static DateTime CastAsDateTime( this DataRow row , string columnName ) { return toDateTime( row[columnName] ) ; } public static DateTime? CastAsDateTimeNullable( this DataRow row , int index ) { return toDateTimeNullable( row[index] ); } public static DateTime? CastAsDateTimeNullable( this DataRow row , string columnName ) { return toDateTimeNullable( row[columnName] ) ; } #region conversion helpers private static DateTime toDateTime( object o ) { DateTime value = (DateTime)o; return value; } private static DateTime? toDateTimeNullable( object o ) { bool hasValue = !( o is DBNull ); DateTime? value = ( hasValue ? (DateTime?) o : (DateTime?) null ) ; return value; } #endregion #endregion downcast to DateTime // ... other implementations elided .. for brevity }
DateTime? dt = null; if (sqldatareader[0] != System.DbNull.Value) { dt = (DateTime)sqldatareader[0]; }
只需使用:
System.Nullable yourVariableName;
让自己轻松:)
如何创建帮助方法
private static DateTime? MyDateConverter(object o) { return (o == DBNull.Value || o == null) ? (DateTime?)null : Convert.ToDateTime(o); }
用法
MyDateConverter(sqldatareader[0])