21

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

編集:2021年3月30日、私がこの質問を書いてから9年になります。最後に、C#9の時点で、この問題は修正されています。三項式は、暗黙的に変換できる限り、混合型をサポートするようになりました。

4

4 に答える 4

52

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

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

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

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

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

于 2012-06-01T15:41:12.063 に答える
6

これは私が別のスレッドで見つけたものであり、私にとってはうまくいきました:

yourVariable ?? (object)DBNull.Value

お役に立てば幸いです。

于 2014-06-10T14:36:58.087 に答える
3

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

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

シナリオでの使用法:

database.AddInParameter(cmd, "@description", DbType.String, 
                           ilo.Description.NullCheck());
于 2012-06-01T16:03:49.557 に答える
2

三項式の両方の部分が同じタイプでなければならないため、コンパイルエラーが発生します。この特定の状況の最も簡単な回避策は、両方をオブジェクトにキャストすることです。

database.AddInParameter(cmd, "@description", DbType.String, 
                           (ilo.Description.Equals(string.Empty)) ?
                            (object) DBNull.Value :
                            (object) ilo.Description);
于 2012-06-01T15:41:28.127 に答える