DbParameter
を使用してフィールドに挿入しようとしているDateTime?
があります。私はそのようなパラメータを作成しています:
DbParameter datePrm = updateStmt.CreateParameter();
datePrm.ParameterName = "@change_date";
そして、null
sを考慮しながら、DateTime?
の値をdataPrm.Value
に入れたいと思います。
最初は賢いと思いました。
datePrm.Value = nullableDate ?? DBNull.Value;
しかし、それはエラーで失敗します
演算子 '??'タイプ「System.DateTime?」のオペランドには適用できませんおよび「System.DBNull」
したがって、2番目の引数が最初の引数のnullを許容しないバージョンである場合にのみ機能すると思います。それで私は行きました:
datePrm.Value = nullableDate.HasValue ? nullableDate.Value : DBNull.Value;
しかし、それも機能しません:
'System.DateTime'と 'System.DBNull'の間の暗黙的な変換がないため、条件式のタイプを判別できません
しかし、私はそれらのタイプの間で変換したくありません!
これまでのところ私が働くことができる唯一のものは:
if (nullableDate.HasValue)
datePrm.Value = nullableDate.Value;
else
datePrm.Value = DBNull.Value;
これが私がこれを書くことができる唯一の方法ですか?三項演算子を使用してワンライナーを機能させる方法はありますか?
更新:理由がわかりません??バージョンが機能しません。 MSDNは言う:
??演算子は、nullでない場合は左側のオペランドを返し、それ以外の場合は右側のオペランドを返します。
それがまさに私が欲しいものです!
pdate2:まあ、結局のところそれは一種の明白でした:
datePrm.Value = nullableDate ?? (object)DBNull.Value;
ああ! @Trebzよりもさらに効率的なソリューションを見つけました!
datePrm.Value = nullableDate ?? (object)DBNull.Value;
SQLServerを使用している場合、System.Data.SqlTypes
名前空間には、煩わしい型キャストを回避するいくつかのユーティリティクラスが含まれています。たとえば、これの代わりに:
var val = (object) "abc" ?? DBNull.Value;
あなたはこれを書くことができます:
var val = "abc" ?? SqlString.Null;
あなたが使用した場合、それはうまくいくでしょう
datePrm.Value = nullableDate.HasValue ? (object)nullableDate.Value : DBNull.Value;
C#3.0を使用している場合は、これを簡単に行う拡張メソッドを作成できます。
public static class DBNullableExtensions
{
public static object ToDBValue<T>(this Nullable<T> value) where T:struct
{
return value.HasValue ? (object)value.Value : DBNull.Value;
}
}
class Program
{
static void Main(string[] args)
{
int? x = null;
Console.WriteLine( x.ToDBValue() == DBNull.Value );
}
}
2回目の試行でのエラーは、nullableDate.ValueとDBNull.Valueが異なる型であり、3項演算子が両方の場合に1つの型を選択する必要があるためだと思います。これをテストする環境はありませんが、これでうまくいくと思います。
datePrm.Value = nullableDate.HasValue ? (object)nullableDate.Value : (object)DBNull.Value;
私が行う方法は、パラメーター値がnullであるかどうかを確認して確認するだけの静的ユーティリティクラスがあることです。次に、値を設定してDBNullを実行します。実行を呼び出す前に、それを実行します。