4

作業中の.netプログラムのコードを見ています。プログラムの前の作者は、1年以上前に私にコードをくれました。突然、触れていないコードから例外がスローされました。

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

例外は、「タイプ'System.DBNull'のオブジェクトをタイプ'System.String'にキャストできません。

文字列はnull許容データ型だと思ったのですが、どうすればこの例外が発生する可能性がありますか?

4

5 に答える 5

9

私はあなたが探しているものは次のとおりだと思います:

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

DBNullとStringの間に暗黙のキャストはありません。

データベースのその列にNULLがなかったため、以前は機能していた可能性があります。一部のデータが破損したか、誰かがテーブルのNOTNULL制約を変更した可能性があります。

基本的に、明示的に何かをキャストする場合は、互換性のある動的タイプがあることを確認することをお勧めします。そうでない場合、例外がスローされます。演算子は基本的に「as可能であればこれにキャストします。そうでない場合は論理値はnullです」と言います。明らかに、as構造体をnullにすることはできないため、演算子は参照型でのみ機能します。

于 2011-11-07T23:05:51.480 に答える
7

DBNullはそれ自体のクラスであり、Valueと呼ばれるプロパティにそれ自体のシングルトンインスタンスが含まれています。DBNull.Valueは、このクラスのインスタンスへの参照であるため、nullと等しくありません。

ほとんどの場合、値がない場合ではDBNull.Valueなく、すべてのデータベースラッパーが返されnullます。この理由の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;

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

于 2011-11-07T23:08:34.780 に答える
4

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

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

于 2011-11-07T23:11:41.480 に答える
3

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

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

はい、stringはnull許容ですが、dbnullをstringにキャストします。dbnullをチェックし、存在する場合はnullに置き換える必要があります。

于 2011-11-07T23:10:58.303 に答える
2

null.NETと.NETには違いがありますDBNull.ValueDBNullここで、クラスとは何か、およびそのクラスのフィールドを確認できます。

あなたはこのようなことをすることができるはずです:

if (row["LevelName"].Value == DBNull.Value)
    return false;
else if (row["LevelName"].ToString() != "ABC")
    // do something
    // ....
于 2011-11-07T23:06:10.427 に答える