質問
私はこれの多くのバージョンを見てきましたが、それらのどれも私のニーズに合ったものではないようです。
私のデータは、DateTimeフィールドのnullを許可するベンダーデータベースからのものです。最初にデータをデータテーブルに引き込みます。
using (SqlCommand cmd = new SqlCommand(sb.ToString(), conn))
using (SqlDataAdapter da = new SqlDataAdapter(cmd))
{
da.Fill(dt);
}
処理のために、データテーブルをリスト<>に変換しています。
var equipment = from i in dt.AsEnumerable()
select new Equipment()
{
Id = i.Field<string>("ID"),
BeginDate = i.Field<DateTime>("BeginDate"),
EndDate = i.Field<DateTime>("EndDate"),
EstimatedLife = i.Field<double>("EstimatedLife")
}
では、この場合にdbnullをチェックするにはどうすればよいですか?方法を書き込もうとしました。
public DateTime CheckDBNull(object dateTime)
{
if (dateTime == DBNull.Value)
return DateTime.MinValue;
else
return (DateTime)dateTime;
}
解決
可能なオプションの1つは、構文を使用した無駄な日付時間として保存することです DateTime?
がここにあります MSDNへのリンク ヌル可能なタイプの使用について
他のヒント
使用する IsDBNull()
System.Convert.IsDBNull(value);
またはあなたが持っている場合 SqlDataReader
reader.IsDBNull(ordinal);
そしてあなたを作ります DateTime
ターゲットになるプロパティ(DateTime?
)そして設定します null
の場合には DBNull
. Field<T>()
これを自動的に行います。
これが私がDateTimesを読むために使用するいくつかのコードの例です
私はそれがより良く書かれることができると確信していますが、私にとってはうまくいきます
public DateTime? ReadNullableDateTimefromReader(string field, IDataRecord data)
{
var a = data[field];
if (a != DBNull.Value)
{
return Convert.ToDateTime(a);
}
return null;
}
public DateTime ReadDateTimefromReader(string field, IDataRecord data)
{
DateTime value;
var valueAsString = data[field].ToString();
try
{
value = DateTime.Parse(valueAsString);
}
catch (Exception)
{
throw new Exception("Cannot read Datetime from reader");
}
return value;
}
これを処理する最も簡単な方法は、「AS」キーワードを使用してデータ型としてフィールドをキャストすることであることがわかりました。これは、nullであり、素晴らしくてシンプルなデータベースフィールドに最適です。
これの詳細については、次の詳細です。 直接キャスティングvs 'as'オペレーター?
例:
IDataRecord record = FromSomeSqlQuerySource;
string nullableString;
DateTime? nullableDateTime;
nullableString = record["StringFromRecord"] as string;
nullableDateTime = record["DateTimeFromRecord"] as DateTime?;
使用する必要があります DataRow["ColumnName"] is DBNull
DateTime Nullを比較します。
例えば:
if(studentDataRow["JoinDate"] is DBNull) { // Do something here }
私はすべてのプロジェクトで使用する一般的な拡張法を書きました:
public static object GetValueSafely<T>(this System.Data.DataTable dt, string ColumnName, int index)
{
if (typeof(T) == typeof(int))
{
if (dt.Rows[index][ColumnName] != DBNull.Value)
return dt.Rows[index][ColumnName];
else
return 0;
}
else if (typeof(T) == typeof(double))
{
if (dt.Rows[index][ColumnName] != DBNull.Value)
return dt.Rows[index][ColumnName];
else
return 0;
}
else if (typeof(T) == typeof(decimal))
{
if (dt.Rows[index][ColumnName] != DBNull.Value)
return dt.Rows[index][ColumnName];
else
return 0;
}
else if (typeof(T) == typeof(float))
{
if (dt.Rows[index][ColumnName] != DBNull.Value)
return dt.Rows[index][ColumnName];
else
return 0;
}
else if (typeof(T) == typeof(string))
{
if (dt.Rows[index][ColumnName] != DBNull.Value)
return dt.Rows[index][ColumnName];
else
return string.Empty;
}
else if (typeof(T) == typeof(byte))
{
if (dt.Rows[index][ColumnName] != DBNull.Value)
return dt.Rows[index][ColumnName];
else
return 0;
}
else if (typeof(T) == typeof(DateTime))
{
if (dt.Rows[index][ColumnName] != DBNull.Value)
return dt.Rows[index][ColumnName];
else
return DateTime.MinValue;
}
else if (typeof(T) == typeof(bool))
{
if (dt.Rows[index][ColumnName] != DBNull.Value)
return dt.Rows[index][ColumnName];
else
return false;
}
if (dt.Rows[index][ColumnName] != DBNull.Value)
return dt.Rows[index][ColumnName];
else
return null;
}
使用例:
private void Example()
{
DataTable dt = GetDataFromDb() // get data from database...
for (int i = 0; i < dt.Rows.Count; i++)
{
Console.WriteLine((DateTime)dt.GetValueSafely<DateTime>("SomeDateColumn", i));
Console.WriteLine((int)dt.GetValueSafely<int>("SomeIntColumn", i));
Console.WriteLine((string)dt.GetValueSafely<string>("SomeStringColumn", i));
}
}