Null ve System.DBNull.Value arasındaki fark nedir?


92

Null ve System.DBNull.Value arasında herhangi bir fark var mı? Eğer evet ise, bu nedir?

Bu davranışı şimdi fark ettim -

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

Döndürülen hiçbir değer yoktur gerçi, bir sql DataReader kullanarak veritabanından veri almak iken if(rdr["Id"] != null)döndü trueve sonunda tamsayı olarak bir null döküm için bir istisna attı.

Ama bu if (rdr["Id"] != System.DBNull.Value)iadeleri kullanırsam false.

Null ve System.DBNull.Value arasındaki fark nedir?


Pekala, alakasızlar. Biri, içindeki bir sınıfın statik bir örneğidir System.Data, diğeri ise bir referansın olmadığını gösteren özel bir değerdir. Birbirleriyle hiçbir alakaları yok. Kafanızın ne olduğunu açıklar mısınız? Asıl sorunuz "neden yerine kendi içlerine koyun DataRowsve DataReaderskoyun ?" DBNull.Valuenull
mqp

Şey, başlangıçta değildi ama söylediklerinizden öğrendikten sonra merak ediyorum. DataRows ve DataReaders'ın neden DBNull.Value'yu null yerine kendi içlerine koyduğunu söyleyebilir misiniz?
pavanred

Ben kendimden emin değilim. İşte bir cevap: stackoverflow.com/questions/4488727/what-is-the-point-of-dbnull/… Null yapılabilir değer türleri C # 'ta bulunmadan önce, uğraşılması daha zor olabilirdi null.
mqp

1
Burada bir cevabım vardı, ancak stackoverflow.com/questions/4488727/what-is-the-point-of-dbnull için daha uygun olduğunu fark ettim - bu yüzden onu hareket
ettirdim

Yanıtlar:


118

Pekala, nullherhangi bir türden bir örnek değil. Aksine, geçersiz bir referanstır.

Ancak, veritabanında var olmayan * değerleri temsil eden ( bir tekildir ve size bu sınıfın tek örneğine bir başvuru verir) System.DbNull.Valueörneğine geçerli bir referanstır .System.DbNullSystem.DbNullSystem.DbNull.Value

* Normalde derdik nullama konuyu karıştırmak istemiyorum.

Yani ikisi arasında büyük bir kavramsal fark var. Anahtar kelime nullgeçersiz bir referansı temsil ediyor. Sınıf System.DbNull, bir veritabanı alanında var olmayan bir değeri temsil eder. Genel olarak, aynı şeyi (bu durumda null) çok farklı iki kavramı temsil etmek için kullanmaktan kaçınmalıyız (bu durumda , bir veritabanı alanında var olmayan bir değere karşı geçersiz bir referans).

Unutmayın, bu yüzden birçok insan genel olarak boş nesne modelini kullanmayı savunuyor , bu da tam System.DbNullolarak bir örnek.


43
+1 Pratik bir örnek: kullanırsanız IDbCommand.ExecuteScalar(), ya boş (kayıt döndürülmez) ya da DbNull(ilk kayıttaki ilk sütun 'var olmayan bir değerdir') döndürebilir . Olmadan DbNullsen birini diğerinden ayırt etmek mümkün olmaz.
C.Evenhuis

Null kullanımını yasaklayan ve bunu kesinlikle 0 ekstra maliyetle yapan bir dil kullanmanızı şiddetle tavsiye ederim. hayat "boş nesne kalıbı" için çok kısa
nicolas

3
Boş bir referans tamamen geçerlidir. ☺
IllidanS4 Monica'yı destekliyor

@ C.Evenhuis Pekala, başka bir genel tavsiye daha var: bir işlev yalnızca bir tür değer döndürmelidir. Bu yüzden insanlar iyi yazılmış TypeScript kodunu tercih ediyor. "Yürütme durumu nedir", "Hesaplama sonucu nedir" den farklıdır. Yani. bu işlevi başka bir şekilde uygulamaya karar vermiş olabilirler (belki bir çıkış parametresi veya HTTP istek yanıtı objelerine benzer bir nesne). Elbette, bu gerçekten istenmeyen bir komplikasyondur, ancak bunu yaptılarsa, DbNull yerine boş kullanılabilir.
klenium

21

DBNull sınıfının belgelerinden :

Nesne yönelimli bir programlama dilinde boş kavramını bir DBNull nesnesiyle karıştırmayın. Nesne yönelimli bir programlama dilinde null, bir nesneye referansın olmaması anlamına gelir. DBNull, başlatılmamış bir varyantı veya var olmayan veritabanı sütununu temsil eder.


11

DBNull.Value uğraşmak zorunda kalmak can sıkıcı.

DBNull olup olmadığını kontrol eden ve ardından değeri döndüren statik yöntemler kullanıyorum.

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

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

Ayrıca, bir DataRow'a değer eklerken "null" kullanamazsınız, DBNull.Value kullanmanız gerekir.

"Boş" ifadesinin iki temsilinin olması, görünürde hiçbir fayda sağlamayan kötü bir tasarımdır.


2
Tiksinme duygusunu paylaşıyoruz: Son ifadeniz sadece bunu okumak için buraya gelip kullanıcı adınızın "tiksindirici" olduğunu
öğrenmenizin ironisiyle gölgeleniyor

5

DBNull.Value, .NET Veritabanı sağlayıcılarının veritabanında boş bir girişi temsil etmek için döndürdüğü şeydir. DBNull.Value null değildir ve bir veritabanı satırından alınan sütun değerleri için null ile karşılaştırmalar çalışmaz, her zaman DBNull.Value ile karşılaştırmalısınız.

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


ps Ayrıca, veritabanına boş bir parametre geçirmek için DBNull.Value kullanmalısınız, aksi takdirde parametre geçilmediği için yorumlanabilir.
James Michael Hare

1
DBNull değildir değil , aynı ADO.NET seçer onu nasıl yorumlanacağı basitçe - "Ne veritabanı döner" şahsen bu yorumun çok değerli olduğundan emin değilim
Marc Gravell

@MarcGravell Evet, Marc, haklısın. Bunu yanlış söyledim. ASP.NET veritabanı boş sütun değerini DBNull.Value'ye çevirir
James Michael Hare

3

DataRow, IsNull()sütunu boş bir değere sahipse test etmek için kullanabileceğiniz çağrılan bir yönteme sahiptir - veritabanı tarafından görülen null ile ilgili.

DataRow["col"]==nullher zaman olacak false.

kullanım

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

yerine.


3

Null, C ++ 'da sıfır göstericiye benzer . Yani herhangi bir değere işaret etmeyen bir referanstır .

DBNull.Valuetamamen farklıdır ve bir alan değeri NULL içerdiğinde döndürülen bir sabittir .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.