web-dev-qa-db-ja.com

三項構文を使用してパラメーターをDBNull.Valueに設定すると、エラーが発生しますか?

SQLServerデータベースにVARCHAR列を設定するためにINSERTステートメントで使用されるパラメーターを設定するための次のコードがあります。私の値オブジェクト(iloという名前)には、String.Emptyに初期化され、XMLから読み取られた値に設定される、またはそのXML要素が空の場合はString.EmptyのままになるDescriptionというプロパティがあります。

したがって、データベースに挿入するときに、プロパティがまだString.Emptyに設定されている場合は、null値を挿入してもらいたいと思います。

database.AddInParameter(cmd, "@description", DbType.String, 
                           (ilo.Description.Equals(string.Empty)) ?
                            DBNull.Value :
                            ilo.Description);

つまり、基本的に、ilo.Descriptionがstring.emptyと等しい場合は、パラメーターをDBNull.Valueに設定し、そうでない場合はilo.Descriptionに設定します。

これにより、VisualStudioで次のエラーが発生します...

エラー141「System.DBNull」と「string」の間に暗黙の変換がないため、条件式のタイプを判別できません

どうして?

不思議な部分は、エラーなしで次のことを実行できることです。これは、上記のようなインライン条件構文を使用する場合とまったく同じです!?!

if(ilo.Description.Equals(string.Empty))
{
    database.AddInParameter(cmd, "@description", DbType.String, DBNull.Value);
}
else
{
    database.AddInParameter(cmd, "@description", DbType.String, ilo.Description);
}

他の投稿を検索して、以下の投稿を見つけましたが、実際には私の質問に答えていません。

「Null」値をパラメータにバインドするEntLibの方法

明らかな回避策は、インライン(三項)構文の代わりにif/elseステートメントを使用することなので、なぜ私はもっと興味がありますか?

このリンクにはある種の答えがありますが、これが機能しないのは私にはBSのように思われるので、より良い説明が必要です。私はそれをバグと呼ぶでしょう!

http://msdn.Microsoft.com/en-us/library/ty67wk28.aspx

18
Jim

これは、条件演算子を使用するときによくあるエラーです。これを修正するには、結果の一方または両方を共通のベースタイプにキャストするだけです。

ilo.Description.Equals(string.Empty) 
     ? (object)DBNull.Value 
     : ilo.Description

この問題は、表示されたエラーメッセージで明らかになります。

'System.DBNull'と 'string'の間に暗黙の変換がないため、条件式のタイプを判別できません

文字列はDBNullではなく、DBNullは文字列ではありません。したがって、コンパイラーは式のタイプを判別できません。共通の基本型(この場合はobject)へのキャストを使用することにより、コンパイラーが文字列もオブジェクトに変換可能であると判断できるシナリオを作成します。これにより、式の型は次のように判断できます。オブジェクト。これは、コード行がDbParameter引数として期待するものともうまく適合します。

44
Anthony Pegram

これは私が別のスレッドで見つけたものであり、それは私にとって素晴らしい働きをしました:

yourVariable ?? (object)DBNull.Value

お役に立てば幸いです。

5
Sagar

アンソニーは確かに正しいので、彼は正しい答えを得るはずです、しかし私が退屈しているのでここに拡張方法があります...

    public static object NullCheck(this string self)
    {
        return (string.IsNullOrEmpty(self)) ? (object)DBNull.Value : self;
    }

シナリオでの使用法:

database.AddInParameter(cmd, "@description", DbType.String, 
                           ilo.Description.NullCheck());
3
Marlon

三元式の両方の部分が同じ型である必要があるため、コンパイルエラーが発生します。この特定の状況に対する最も簡単な回避策は、両方をオブジェクトにキャストすることです。

database.AddInParameter(cmd, "@description", DbType.String, 
                           (ilo.Description.Equals(string.Empty)) ?
                            (object) DBNull.Value :
                            (object) ilo.Description);
2
Tuan