Czy jest jakaś różnica między null i System.DBNull.Value? Jeśli tak, co to jest?
Zauważyłem teraz to zachowanie -
while (rdr.Read())
{
if (rdr["Id"] != null) //if (rdr["Id"] != System.DBNull.Value)
{
int x = Convert.ToInt32(rdr["Id"]);
}
}
A ja pobierania danych z bazy danych przy użyciu DataReader SQL, choć nie ma wartości zwracane if(rdr["Id"] != null)
powrócił true
i ostatecznie zwrócił wyjątek odlewania null jako całkowitą.
Ale to, jeśli używam if (rdr["Id"] != System.DBNull.Value)
zwrotów false
.
Jaka jest różnica między wartością null a System.DBNull.Value?
System.Data
, a druga to specjalna wartość oznaczająca brak desygnatu. Nie mają ze sobą nic wspólnego. Czy możesz wyjaśnić, w czym jesteś zdezorientowany? Czy Twoje prawdziwe pytanie brzmi: „dlaczego robićDataRows
iDataReaders
wkładaćDBNull.Value
w siebie zamiastnull
?”null
.Odpowiedzi:
Cóż,
null
nie jest to żaden typ. Jest to raczej nieprawidłowe odniesienie.Jednak
System.DbNull.Value
jest prawidłowym odwołaniem do wystąpieniaSystem.DbNull
(System.DbNull
jest singletonem iSystem.DbNull.Value
zawiera odniesienie do pojedynczego wystąpienia tej klasy), które reprezentuje nieistniejące * wartości w bazie danych.* Normalnie powiedzielibyśmy
null
, ale nie chcę mylić problemu.Tak więc istnieje między nimi duża różnica pojęciowa. Słowo kluczowe
null
reprezentuje nieprawidłowe odniesienie. KlasaSystem.DbNull
reprezentuje nieistniejącą wartość w polu bazy danych. Generalnie powinniśmy unikać używania tego samego (w tym przypadkunull
) do reprezentowania dwóch bardzo różnych koncepcji (w tym przypadku nieprawidłowe odwołanie w porównaniu z nieistniejącą wartością w polu bazy danych).Należy pamiętać, że dlatego wiele osób w ogóle opowiada się za użyciem wzorca obiektu zerowego , który jest dokładnie tym
System.DbNull
przykładem.źródło
IDbCommand.ExecuteScalar()
, może zwrócić wartość null (brak zwróconych rekordów) lubDbNull
(pierwsza kolumna w pierwszym rekordzie to „nieistniejąca wartość”). BezDbNull
Ciebie nie byłbyś w stanie odróżnić jednego od drugiego.Z dokumentacji klasy DBNull :
źródło
DBNull.Value jest irytujące.
Używam metod statycznych, które sprawdzają, czy to DBNull, a następnie zwracają wartość.
SqlDataReader r = ...; String firstName = getString(r[COL_Firstname]); private static String getString(Object o) { if (o == DBNull.Value) return null; return (String) o; }
Ponadto, podczas wstawiania wartości do DataRow, nie możesz użyć „null”, musisz użyć DBNull.Value.
Dwie reprezentacje „null” to zły projekt bez widocznych korzyści.
źródło
DBNull.Value jest tym, co dostawcy bazy danych .NET zwracają, aby reprezentować pusty wpis w bazie danych. DBNull.Value nie ma wartości null i porównania z wartością null dla wartości kolumn pobranych z wiersza bazy danych nie będą działać, należy zawsze porównać z wartością DBNull.Value.
http://msdn.microsoft.com/en-us/library/system.dbnull.value.aspx
źródło
DataRow ma wywoływaną metodę,
IsNull()
której można użyć do przetestowania kolumny, jeśli ma wartość null - w odniesieniu do wartości null widzianej przez bazę danych.DataRow["col"]==null
zawsze będziefalse
.posługiwać się
DataRow r; if (r.IsNull("col")) ...
zamiast.
źródło
Null jest podobne do wskaźnika zerowego w C ++ . Jest to więc odniesienie, które nie wskazuje na żadną wartość .
DBNull.Value
jest zupełnie inna i jest stałą, która jest zwracana, gdy wartość pola zawiera NULL.źródło