¿Cuál es la diferencia entre null y System.DBNull.Value?

¿Hay alguna diferencia entre null y System.DBNull.Value? ¿Y si si, que?

Me di cuenta de este comportamiento ahora –

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

Mientras recupero datos de la base de datos usando un lector de datos sql, aunque no se devuelve ningún valor if(rdr["Id"] != null) devolvió true y finalmente arrojó una excepción para convertir un nulo como un entero.

Pero, esto si uso if (rdr["Id"] != System.DBNull.Value) devuelve false .

¿Cuál es la diferencia entre null y System.DBNull.Value?

Bueno, null no es una instancia de ningún tipo. Más bien, es una referencia inválida.

Sin embargo, System.DbNull.Value , es una referencia válida a una instancia de System.DbNull ( System.DbNull es un singleton y System.DbNull.Value le da una referencia a la única instancia de esa clase) que representa valores inexistentes * en la base de datos.

* Normalmente diríamos null , pero no quiero confundir el problema.

Entonces, hay una gran diferencia conceptual entre los dos. La palabra clave null representa una referencia no válida. La clase System.DbNull representa un valor inexistente en un campo de base de datos. En general, deberíamos intentar evitar utilizar lo mismo (en este caso, null ) para representar dos conceptos muy diferentes (en este caso, una referencia no válida frente a un valor inexistente en un campo de base de datos).

Tenga en cuenta que esta es la razón por la cual muchas personas abogan por usar el patrón de objeto nulo en general, que es exactamente de lo que System.DbNull es un ejemplo.

De la documentación de la clase DBNull :

No confunda la noción de nulo en un lenguaje de progtwigción orientado a objetos con un objeto DBNull. En un lenguaje de progtwigción orientado a objetos, null significa la ausencia de una referencia a un objeto. DBNull representa una variante no inicializada o una columna de base de datos inexistente.

DBNull.Value es molesto de tener que tratar.

Utilizo métodos estáticos que comprueban si es DBNull y luego devuelven el valor.

 SqlDataReader r = ...; String firstName = getString(r[COL_Firstname]); private static String getString(Object o) { if (o == DBNull.Value) return null; return (String) o; } 

Además, al insertar valores en un DataRow, no puede usar “null”, tiene que usar DBNull.Value.

Tener dos representaciones de “nulo” es un mal diseño sin beneficio aparente.

DBNull.Value es lo que los proveedores de la base de datos .NET devuelven para representar una entrada nula en la base de datos. DBNull.Value no es nulo y las comparaciones con null para los valores de columna recuperados de una fila de base de datos no funcionarán, siempre se debe comparar con DBNull.Value.

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

DataRow tiene un método que se llama IsNull() que puede usar para probar la columna si tiene un valor nulo, con respecto al nulo tal como lo ve la base de datos.

DataRow["col"]==null será false .

utilizar

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

en lugar.

Null es similar al puntero cero en C ++ . Entonces es una referencia que no apunta a ningún valor .

DBNull.Value es completamente diferente y es una constante que se devuelve cuando un valor de campo contiene NULL.