私のSQLServerデータベースにはnull許容のDateTime値が含まれています。 C#のアプリケーションでそれらをnull許容のDateTimeオブジェクトに変換するにはどうすればよいですか?
これは私がそれがどのように見えるかと思うものですが、そうではありません:
DateTime? dt = (DateTime?) sqldatareader[0];
SQLnullは.NETnullと同じではありません。 System.DBNull.Valueと比較する必要があります。
_object sqlDateTime = sqldatareader[0];
DateTime? dt = (sqlDateTime == System.DBNull.Value)
? (DateTime?)null
: Convert.ToDateTime(sqlDateTime);
_
あなたのコメントに答えて、Item
のDataReader
プロパティのデータ型は、基礎となるデータベースタイプのデータ型です。 null以外のSQLServerデータベースの場合は_System.Data.SqlTypes.SqlDateTime
_、null列の場合は_System.DBNull
_、ODBCデータベースの場合は_System.Data.Odbc.OdbcTypes.SmallDateTime
_、または実際には信頼できるのは、タイプがobject
であるということだけです。
これが、DateTime
に型強制の代わりにConvert.ToDateTime()
を使用することを提案する理由でもあります。 ODBCまたは任意の日付列を.NETDateTime
に強制変換できるという保証はありません。コメントで「sqldatareader」とSQLServer _System.Data.SqlTypes.SqlDateTime
_は確かに_System.DateTime
_に強制変換できますが、元の質問ではそれはわかりませんでした。
DataReader
sの使用の詳細については、 [〜#〜] msdn [〜#〜] を参照してください。
私は最近このトリックを見つけました、それは簡単です:
DateTime? dt = sqldatareader[0] as DateTime?;
値が単なるnullではなく「DBNull」であるかどうかを確認する必要があります。ブログに小さなヘルパークラスを投稿しました: http://improve.dk/archive/2007/10/08/handling-dbnulls.aspx
クラスを実装したら、次のように使用します。
DateTime? dt = DBConvert.To<datetime?>(sqldatareader[0]);
少し前に、私はDataRowがこの種のダウンキャストを実行するための一連の拡張メソッドを作成しました...繰り返しの戯言を書くのは嫌だからです。使い方は簡単です:
_foreach( DataRow dr in someDataTable )
{
DateTime? dt = dr.CastAsDateTimeNullable( "lastUpdated" ) ;
int id = dr.CastAsInt( "transactionID" ) ;
// etc.
}
_
これがDateTime値の一部です。他のデータ型の実装を追加するのは非常に簡単です。 DataReaderに同じようなことをするのは、それほど難しいことではありません。
ジェネリックメソッドを考え出そうとしましたが、ジェネリックの実行方法に制限があるため、実行が困難または不可能であり、希望する動作を得ることができました(たとえば、default(T)
ではなくnull
値— _0
_とnull
... difficultを区別するSQLNULLのデフォルト値を取得します。
_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
}
_
ヘルパーメソッドを作成するのはどうですか
private static DateTime? MyDateConverter(object o)
{
return (o == DBNull.Value || o == null) ? (DateTime?)null : Convert.ToDateTime(o);
}
使用法
MyDateConverter(sqldatareader[0])
DateTime? dt = null;
if (sqldatareader[0] != System.DbNull.Value)
{
dt = (DateTime)sqldatareader[0];
}
使用するだけです:
System.Nullable<System.DateTime> yourVariableName;
自分で簡単にしてください:)