nullとSystem.DBNull.Valueの違いは何ですか?


92

nullとSystem.DBNull.Valueの間に違いはありますか?はいの場合、それは何ですか?

私はこの動作に気づきました-

while (rdr.Read())
{
    if (rdr["Id"] != null) //if (rdr["Id"] != System.DBNull.Value)  
    {
        int x = Convert.ToInt32(rdr["Id"]);
    }
}

sql datareaderを使用してデータベースからデータを取得していますが、if(rdr["Id"] != null)返される値はなくtrue、最終的にnullを整数としてキャストするための例外がスローされました。

しかし、これを使用すると、if (rdr["Id"] != System.DBNull.Value)returnが返されますfalse

nullとSystem.DBNull.Valueの違いは何ですか?


まあ、彼らは無関係です。1つはのクラスの静的インスタンスで、もう1つはSystem.Data指示対象がないことを示す特別な値です。彼らは互いに何の関係もありません。混乱している点について詳しく説明できますか?あなたの本当の質問は、「なぜDataRows、代わりに自分の中にDataReaders身を置くDBNull.Valuenullですか?」
mqp '10

さて、私は最初はそうではありませんでしたが、あなたの言ったことから学んだ後、私は興味があります。DataRowsとDataReadersがDBNull.Valueをnullではなくそれ自体に配置する理由を教えてください。
2011

私自身はよくわかりません。ここでは1つの答えがあります:stackoverflow.com/questions/4488727/what-is-the-point-of-dbnull/...それがNULL可能値の型は、C#で周りにいた前に、それがよりに対処するための手間であったであろうことも可能ですnull
mqp

1
ここで答えはありましたが、stackoverflow.com /
questions / 4488727 / what

回答:


116

まあ、nullどのタイプのインスタンスでもありません。むしろ、これは無効な参照です。

ただし、は、データベース内に存在しない*値を表す(シングルトンであり、そのクラスの単一インスタンスへの参照を提供します)のSystem.DbNull.Valueインスタンスへの有効な参照です。System.DbNullSystem.DbNullSystem.DbNull.Value

*通常はと言いますnullが、問題を混乱させたくありません。

したがって、2つの間には大きな概念上の違いがあります。キーワードnullは無効な参照を表します。クラスSystem.DbNullは、データベースフィールドに存在しない値を表します。一般に、null2つの非常に異なる概念(この場合は無効な参照とデータベースフィールドに存在しない値)を表すために同じもの(この場合は)を使用しないようにする必要があります。

心に留めておいてください。これが、多くの人々が一般的にnullオブジェクトパターンの使用を提唱する理由System.DbNullです。これはまさにその例です。


43
+1実用的な例:を使用するとIDbCommand.ExecuteScalar()、null(レコードが返されない)またはDbNull(最初のレコードの最初の列が「存在しない値」)を返す場合があります。DbNullあなたがいなければ、一方を他方から区別することができません。
C.Evenhuis 2013

Nullの使用を禁止する言語を使用することを強くお勧めします。これにより、追加費用はまったくかかりません。「ヌルオブジェクトパターン」には寿命が短すぎる
ニコラス

3
null参照は完全に有効です。☺
IllidanS4はモニカのバック望んで

@ C.Evenhuisさて、もう1つの一般的なアドバイスがあります。関数は1つのタイプの値のみを返す必要があります。そのため、よく型付けされたTypeScriptコードが好まれます。「実行状況とは」と「計算結果とは」が異なります。つまり。彼らはこの関数を別の方法で実装することを決定した可能性があります(おそらく出力パラメーター、またはHTTP要求応答オブジェクトに類似したオブジェクト)。確かに、これは本当に望まれる複雑化ではありませんが、そうした場合は、DbNullの代わりにnullを使用できます。
クレニウム

21

DBNullクラスのドキュメントから:

オブジェクト指向プログラミング言語のnullの概念とDBNullオブジェクトを混同しないでください。オブジェクト指向プログラミング言語では、nullはオブジェクトへの参照がないことを意味します。DBNullは、初期化されていないバリアントまたは存在しないデータベース列を表します。


11

DBNull.Valueは扱いが面倒です。

私はそれがDBNullであるかどうかをチェックして値を返す静的メソッドを使用しています。

SqlDataReader r = ...;
String firstName = getString(r[COL_Firstname]);

private static String getString(Object o) {
   if (o == DBNull.Value) return null;
   return (String) o;
}

また、DataRowに値を挿入する場合は、「null」を使用できません。DBNull.Valueを使用する必要があります。

「null」の2つの表現を持つことは、明らかな利点がないために悪い設計です。


2
私たちが共有する嫌悪感の感情:あなたの最後の声明は、これを読んでユーザー名が「
嫌い

5

DBNull.Valueは、データベースのnullエントリを表すために.NETデータベースプロバイダーが返すものです。DBNull.Valueはnullではなく、データベース行から取得した列値のnullとの比較は機能しません。常にDBNull.Valueと比較する必要があります。

http://msdn.microsoft.com/en-us/library/system.dbnull.value.aspx


psまた、DBNull.Valueを使用してnullパラメータをデータベースに渡す必要があります。それ以外の場合は、パラメータが渡されなかったために解釈される可能性があります。
ジェームズマイケルヘア

1
DBNullは「データベースが返すもの」ではなく、単にADO.NETがデータベースを解釈する方法です。個人的に私はこの解釈は非常に貴重であることはよく分からない
マルクGravell

@MarcGravellはい、マルク、あなたは正しいです。私はそれを間違って言いました。ASP.NETはデータベースのnull列の値をDBNull.Valueに変換します
James Michael Hare

3

DataRowにはIsNull()、データベースに表示されるnullに関して、null値がある場合に列をテストするために使用できるメソッドが呼び出されます。

DataRow["col"]==null常にになりますfalse

使用する

DataRow r;
if (r.IsNull("col")) ...

代わりに。


3

nullは、C ++のゼロポインターに似ています。そのため、値を参照しない参照です

DBNull.Value完全に異なり、フィールド値にNULLが含まれている場合に返される定数です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.