web-dev-qa-db-ja.com

C#ADO.NET:nullとDbNull-より効率的な構文はありますか?

DbParameterを使用してフィールドに挿入しようとしているDateTime?があります。私はそのようなパラメータを作成しています:

DbParameter datePrm = updateStmt.CreateParameter();
datePrm.ParameterName = "@change_date";

そして、nullsを考慮しながら、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;
48
Stewart Johnson

ああ! @Trebzよりもさらに効率的なソリューションを見つけました!

datePrm.Value = nullableDate ?? (object)DBNull.Value;
62
Stewart Johnson

SQLServerを使用している場合、System.Data.SqlTypes名前空間には、煩わしい型キャストを回避するいくつかのユーティリティクラスが含まれています。たとえば、これの代わりに:

var val = (object) "abc" ?? DBNull.Value;

あなたはこれを書くことができます:

var val = "abc" ?? SqlString.Null;
6

あなたが使用した場合、それはうまくいくでしょう

datePrm.Value = nullableDate.HasValue ? (object)nullableDate.Value : DBNull.Value;
5
dnolan

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 );
    }
}
5
Pop Catalin

2回目の試行でのエラーは、nullableDate.ValueとDBNull.Valueが異なる型であり、3項演算子が両方の場合に1つの型を選択する必要があるためだと思います。これをテストする環境はありませんが、これでうまくいくと思います。

datePrm.Value = nullableDate.HasValue ? (object)nullableDate.Value : (object)DBNull.Value;
1
Dan

私が行う方法は、パラメーター値がnullであるかどうかを確認して確認するだけの静的ユーティリティクラスがあることです。次に、値を設定してDBNullを実行します。実行を呼び出す前に、それを実行します。

0
Darren Kopp