Pregunta ¿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) devuelto true y finalmente lanzó una excepción para convertir un nulo como un número entero.

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

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


76
2018-02-10 14:33


origen


Respuestas:


Bien, 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 inexistente* valores en la base de datos.

* Normalmente decimos null, pero no quiero confundir el problema.

Entonces, hay una gran diferencia conceptual entre los dos. La palabra clave null representa una referencia inválida La clase System.DbNull representa un valor inexistente en un campo de base de datos. En general, debemos tratar de evitar usar 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 patrón de objeto nulo en general, que es exactamente lo que System.DbNull es un ejemplo de.


95
2018-02-10 14:36



De la documentación del Clase DBNull:

No confunda la noción de nulo en un lenguaje de programación orientado a objetos con un objeto DBNull. En un lenguaje de programació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.


20
2018-02-10 14:38



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.


9
2018-06-25 22:34



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


5
2018-02-10 14:35



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 siempre será false.

utilizar

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

en lugar.


3
2018-02-10 14:37



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

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


3
2018-02-10 14:38