2010-08-06 12 views
7

Ho definito Classe Persona proprietà Compleanno come nullable DateTime?, quindi perché l'operatore null coalescing non dovrebbe funzionare nell'esempio seguente?C# ?? Domanda operatore coalescente null

cmd.Parameters.Add(new SqlParameter("@Birthday", 
    SqlDbType.SmallDateTime)).Value =  
    person.Birthday ?? DBNull.Value; 

Il compilatore err che ho ricevuto era "Operatore" ?? non può essere applicato agli operandi di tipo 'System.DateTime?' e 'System.DBNull'"

seguito anche ottenuto un errore di compilazione:

cmd.Parameters.Add(new SqlParameter("@Birthday", 
    SqlDbType.SmallDateTime)).Value = 
    (person.Birthday == null) ? person.Birthday:DBNull.Value; 

ho aggiunto un cast (oggetto) come raccomandato dal refactoring, e compilato, ma non ha funzionato correttamente e il valore è stato memorizzato nel sqlserver db come null in entrambi i casi.

SqlDbType.SmallDateTime)).Value =  
     person.Birthday ?? (object)DBNull.Value; 

Qualcuno può spiegare cosa sta succedendo qui?

avevo bisogno di usare il seguente codice goffo:

if (person.Birthday == null) 
    cmd.Parameters.Add("@Birthday", SqlDbType.SmallDateTime).Value 
     = DBNull.Value; 
    else cmd.Parameters.Add("@Birthday", SqlDbType.SmallDateTime).Value = 
      person.Birthday; 
+3

Duplicato di http://stackoverflow.com/questions/218808/c-ado-net-nulls-and-dbnull-is-there-more-efficient-syntax – sgriffinusa

+0

Ottenuto da un altro post: SqlDbType.SmallDateTime)) .Value = person.Birthday ?? (Oggetto) DBNull.Value; Grazie! –

risposta

20

Il problema è che DateTime? e DBNull.Value non sono dello stesso tipo, quindi non è possibile utilizzare l'operatore null coalescenza su di loro.

Nel tuo caso si può fare person.Birthday ?? (object)DBNull.Value per passare un valore di tipo object fino alla Add()

3

Il tuo primo problema è che per l'operatore ?? o ?:, gli oggetti per entrambe le scelte devono essere dello stesso tipo. Qui sono di tipo diverso.

+1

Quindi cosa significa '?:' Fare? edit: non importa, lo sapevo, non ho mai visto quei 2 simboli messi insieme così prima. http://msdn.microsoft.com/en-us/library/ty67wk28.aspx –

3

preferisco iterare i miei parametri poco prima di eseguire la query, cambiando tutte le istanze di nulla a DBNull a seconda dei casi, ad esempio:

foreach (IDataParameter param in cmd.Parameters) 
    if (param.Value == null) 
     param.Value = DBNull.Value; 

Questo mi permette di lasciare i valori nulli così com'è e semplicemente scambiarlo fuori in massa più tardi.

+0

Per me questo è pulito e semplice, buona risposta. –

+0

Il mio problema con questo è l'overhead aggiuntivo dell'iterazione dei parametri dopo il fatto, rispetto alla loro gestione immediata. – Andrew