2011-11-07 2 views
4

私が取り組んでいる.netプログラムのいくつかのコードを見ています。プログラムの前の作者は、1年以上前に私にコードを与えました。突然、私は触れていないコードからスローされた例外を見ています:ヌル文字列とDBNullについて混乱しています

if ((string)row["LevelName"] != "ABC") 

例外は「型のオブジェクトをキャストすることができない 『System.DBNull』 『可能System.String』を入力する

私はその文字列がNULL可能データタイプだと思ったので、どのように私はおそらくこの例外を取得することができます

+0

このコードは1年以上にわたって正常に動作しています。私はどこかに何かを混乱させているに違いないと感じる –

+0

うん、実際には、私はした。問題のコードは、実行していた特定のクエリに対して決して上がるべきではないため、DBNull値の準備ができていませんでした。私は、クエリを変更する際に間違いを犯し、エラーが発生しました。 –

+0

有益な答えをいただき、ありがとうございます。私はそれらすべてを投票しました。私が読んだSQLの本は、 "その4文字の単語"と呼んでも不思議ではありません。 –

答えて

7

DBNullValueと呼ばれるプロパティにitsselfのsingletonインスタンスを含むそれ自身のクラスです。 DBNull.Valueは、このクラスのインスタンスへの参照であるため、nullと等しくありません。

ほとんどのデータベースラッパーでは、値がない場合はnullの代わりにDBNull.Valueが返されます。この理由の1つは、実際のnullを返すことは、列にnull値だけでなく、行が全くないことを意味する可能性があります(値を取得するために使用するオブジェクトによって異なります)。

通常、as演算子はDBNullで非常に便利で、任意のnull可能型(stringを含む)で使用できます。

string str = reader["Name"] as string; 
int? i = reader["Age"] as int?; 

(それはあまりにもかなり見ていませんが)あなたがnull非許容値型を必要とするときそれはまた、??オペレータはここにも非常に便利であることを言及する価値があるかもしれません。

int i = reader["Age"] as int? ?? -1; 

これは、LINQのselect句でちょっとしたシナリオとして非常に便利です。

+0

私の早い指私は恐れている。幸運にも、あなたがそのコメントを残す前に2分後の記事を編集して、**正しい**の例を得ました。申し訳ありません。 – Connell

+0

問題はありません、私はコメントと+1を削除しました。 – Rob

9

私はあなたが探しているものと信じている:?暗黙のキャストはありません

if ((row["LevelName"] as String) != "ABC") 

DBNullとStringの間。

データベース内のその列にNULLが存在しなかったので、以前は動作していた可能性があります。たぶん一部のデータが破損しているか、テーブルのNOT NULL制約を変更した人がいます。

明示的に明示的にキャストする場合は、互換性のある動的型があることを確認することをお勧めします。それ以外の場合は例外がスローされます。 asオペレータは、基本的には「可能であればキャストします。それ以外の場合は論理値はnullです」と言います。明らかに、as演算子は、structがnullになり得ないため、参照型に対してのみ機能します。

+2

あなたの答えはこれを意味しますが、 '変数をTypeとして使う'は、明示的キャスト '(Type)変数を使うと' InvalidCastException'が発生する場合に 'null'を返します。 – Rob

2

.NET nullDBNull.Valueの間に違いがあります。ここでは、DBNullクラスが何であるか、そしてそのクラスのValueフィールドを確認できます。あなたはこのような何か行うことができるはず

if (row["LevelName"].Value == DBNull.Value) 
    return false; 
else if (row["LevelName"].ToString() != "ABC") 
    // do something 
    // .... 
3

DBNullは、データベースのNULL値を表します。これは空の参照を示す.NETのnullと同じではありません。

誰かがnullを持つレコードを変更または挿入したため、コードが突然失敗する。

はい、文字列はNULL可能ですが、文字列にdbnullをキャストします。 dbnullをチェックし、存在する場合はnullに置き換える必要があります。

4

DBNullは、指定されたデータベース列にデータが存在しないことを意味します。これは、新しいレコードがデータベースに作成されたが、 "LevelName"列に値が割り当てられていない場合に発生する可能性があります。

DBNullはnullオブジェクト参照またはNULL文字列変数と同じではありません。 DBNullは、列データが決して設定されていないことを意味します。 "LevelName"列にnullを割り当てると、列が初期化され、NULL(DBNullではなく)が返されます。

関連する問題