2012-06-01 6 views
15

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

データベースに挿入するとき、プロパティがまだString.Emptyに設定されている場合は、null値を挿入する必要があります。

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

だから基本的に私はそうilo.Descriptionに設定し、ilo.DescriptionがString.Emptyをと等しい場合、DBNull.Valueをにパラメータを設定し、言っています。 「System.DBNull」と「文字列」

なぜ間には暗黙的な変換が存在しないため、これは、Visual Studioで次のエラーを与える

...条件式の

エラー141種類を決定することができないのですか?

好奇心の部分は、エラーなしで次のことができます。これは、上記のようなインライン条件構文を使用するのとまったく同じです。

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

私は他の記事を検索し、下記のものを見つけましたが、実際に私の質問には答えません。

EntLib Way to Bind "Null" Value to Parameter

明白な回避策は、だけではなく、インラインの場合/ else文(三元)の構文を使用することですので、私は、なぜ、より興味がありますか?

このリンクにはある種の回答がありますが、これはうまくいきません。私はそれをバグと呼ぶだろう!

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

+1

あなたは(http://stackoverflow.com/questions/4290203/simple-c-why-assigning-null-in-ternary-operator-fails [この回答に]三項演算子とこの種の問題についての詳細を得ることができます-no-implicit-conversion) – Steve

+0

Steveに感謝します。あなたのリンクは私が本当に探していたものでした。私はこれが.NETの愚かな側面だと思う。それぞれの可能な結果の種類がステートメントに適合するかどうかを評価するだけではどうですか?つまり、オブジェクトo =(someBool)と言ったら? someInt32:someString;エラーが発生しますが、someStringをsomeInt32にキャストできるかどうかを評価するのではなく、両方の結果をObjectに暗黙的にキャストできるかどうか評価するのは簡単でしょうか?それは私には馬鹿だと思われますが、それはどういうものかと思います。ありがとう! – Jim

+0

私はこのスレッドへの返答のスピードと正確さに非常に感銘を受けたことをコメントしたいと思います。このコミュニティは素晴らしいです!みんな、ありがとう! – Jim

答えて

34

これは条件演算子を使用しているとき、人々が受け取る一般的なエラーです。それを修正するには、結果の一方または両方を共通の基本タイプにキャストするだけです。

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

問題は、表示されたエラーメッセージで明らかになります。 「System.DBNull」と「列」

列の間には暗黙的な変換が存在しないための条件式の

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

+0

Steveのコメントはより詳細な情報を提供しますが、あなたの答えも非常に正しいです。ちょうど私にそれをしなくてはならないと思う。私はJavaでこれが起こらないと信じています。 – Jim

1

三項式の両方の部分が同じ型でなければならないため、コンパイルエラーが発生します。この特定の状況のた​​めの最も簡単な回避策は、オブジェクトの両方をキャストすることです:私は退屈だから、彼は正しい答えを得る必要がありますので

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

lazyberezovskyが示唆しているように、ここではDBNull.Valueではなくnullを使用する方が良いでしょう。私は、datareaderまたはdatasetから読み取るときにDBNull.Valueを使うだけでよいと思う。 – Tuan

2

アンソニーは確かに正しいです、しかしここでは...拡張メソッドです

あなたのシナリオで
public static object NullCheck(this string self) 
    { 
     return (string.IsNullOrEmpty(self)) ? (object)DBNull.Value : self; 
    } 

用法:

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

良いもの。私はおそらくこのメソッドを使用しませんが、それは私に以前知らなかったC#についてのいくつかのことを教えてくれました。以前はStringのIsNullOrEmptyメソッドに気付かなかったようです。私はちょうどJavaに慣れており、もっとC#を学ぶのはうれしいです。ありがとう! – Jim

+0

それを考えた上で、ParameterCollection /データベースオブジェクト自体に拡張メソッドを配置して、必要な方法でnullを処理するラッパーを提供するほうが良いかもしれません。 – Marlon

4

これは私が別のスレッドで見つかった、それは私のために素晴らしい仕事です:

yourVariable ?? (object)DBNull.Value 

私はそれが役に立てば幸い。

関連する問題