2011-02-10 15 views
71

C'è qualche differenza tra null e System.DBNull.Value? Se sì, che cos'è?Qual è la differenza tra null e System.DBNull.Value?

ho notato questo comportamento la società -

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

Mentre io recuperare i dati dal database utilizzando una datareader SQL, anche se non v'è alcun valore restituito if(rdr["Id"] != null) ritornato true e alla fine ha generato un'eccezione per lanciare una null come numero intero.

Ma, questo se uso if (rdr["Id"] != System.DBNull.Value) restituisce false.

Qual è la differenza tra null e System.DBNull.Value?

+0

Beh, non sono correlati. Uno è un'istanza statica di una classe in 'System.Data', e l'altro è un valore speciale che indica la mancanza di un referente. Non hanno niente a che fare l'uno con l'altro. Puoi approfondire ciò di cui sei confuso? La tua vera domanda è "perché i' DataRows' e 'DataReaders' mettono' DBNull.Value' dentro se stessi invece di 'null'?" – mquander

+0

Beh, non è stato inizialmente ma dopo aver imparato da quello che hai detto, sono curioso. Potresti dirmi perché DataRows e DataReader inseriscono DBNull.Value in se stessi anziché null? – pavanred

+0

Non sono sicuro di me stesso. Ecco una risposta: http://stackoverflow.com/questions/4488727/what-is-the-point-of-dbnull/4488758#4488758 È anche possibile che prima che i tipi di valori nullable fossero in C#, sarebbe stato più di una seccatura per trattare con 'null'. – mquander

risposta

89

Beh, null non è un'istanza di qualsiasi tipo. Piuttosto, è un riferimento non valido.

Tuttavia, System.DbNull.Value, è una valida riferimento a un'istanza di System.DbNull (System.DbNull è un Singleton e System.DbNull.Value ti dà un riferimento alla singola istanza di quella classe) che rappresenta inesistenti * valori nel database.

* Direi normalmente null, ma non voglio confondere il problema.

Quindi, c'è una grande differenza concettuale tra i due. La parola chiave null rappresenta un riferimento non valido. La classe System.DbNull rappresenta un valore inesistente in un campo del database. In generale, dovremmo evitare di utilizzare la stessa cosa (in questo caso null) per rappresentare due concetti molto diversi (in questo caso un riferimento non valido rispetto a un valore inesistente in un campo del database).

Tenete a mente, questo è il motivo per cui molte persone sostengono l'uso del null object pattern in generale, che è esattamente ciò che è un esempio di System.DbNull.

+31

+1 Un esempio pratico: se si utilizza 'IDbCommand.ExecuteScalar()', può restituire null (nessun record restituito) o 'DbNull' (prima colonna in primo record è un 'valore inesistente'). Senza 'DbNull' non saresti in grado di distinguere l'uno dall'altro. –

+0

Consiglio vivamente di utilizzare un linguaggio che vieta l'uso di Null e lo fa ad un costo assolutamente 0 aggiuntivo. la vita è troppo breve per "null object pattern" – nicolas

+2

Un riferimento null è perfettamente valido. ☺ – IllidanS4

5

DBNull.Value è ciò che i provider di database .NET restituiscono per rappresentare una voce nulla nel database. DBNull.Value non è nullo e il confronto con null per i valori di colonna recuperati da una riga del database non funziona, è sempre necessario confrontare con DBNull.Value.

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

+0

p.s. Dovresti inoltre utilizzare DBNull.Value per passare un parametro null al database, altrimenti potrebbe essere interpretato come il parametro non è stato passato. –

+0

DBNull è * non * "ciò che restituisce il database" - è semplicemente come ADO.NET sceglie di interpretarlo; personalmente non sono sicuro che questa interpretazione sia molto preziosa –

+0

@MarcGravell Sì, Marc, hai ragione. Ho formulato in modo errato. ASP.NET traduce il valore della colonna null del database in DBNull.Value –

3

DataRow ha un metodo che si chiama IsNull() che è possibile utilizzare per testare la colonna se ha un valore nullo, rispetto al valore null visto dal database.

DataRow["col"]==null sarà sempre false.

uso

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

invece.

2

Null è simile a puntatore zero in C++. Quindi è un riferimento che non punta a nessun valore.

DBNull.Value è completamente diverso ed è una costante che viene restituita quando un valore di campo contiene NULL.

20

Dalla documentazione del DBNull class:

Non confondere il concetto di null in un linguaggio di programmazione orientato agli oggetti con un oggetto DBNull. In un linguaggio di programmazione orientato agli oggetti, null indica l'assenza di un riferimento a un oggetto. DBNull rappresenta una variante non inizializzata o una colonna di database inesistente.

8

DBNull.Value è fastidioso avere a che fare con.

Uso metodi statici che controllano se è DBNull e restituiscono il valore.

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

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

Inoltre, quando si inseriscono valori in un DataRow, non è possibile utilizzare "null", è necessario utilizzare DBNull.Value.

Sono due rappresentazioni di "null" è un cattivo progetto senza alcun beneficio apparente.

Problemi correlati