2010-08-06 20 views
7

He definido la clase persona propiedad cumpleaños como nullable DateTime?, entonces ¿por qué no debería funcionar el operador nulo coalescente en el siguiente ejemplo?C# ?? nulo coalescente operador pregunta

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

El error de compilación que obtuve fue "Operator" ?? no se puede aplicar a operandos del tipo 'System.DateTime?' y 'System.DBNull'"

Lo siguiente también tiene un error de compilación:

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

añadí un yeso para (objeto) según lo recomendado por Refactor, y compilado, pero no funcionaba correctamente y el valor se almacenó en sqlserver db como nulo en ambos casos.

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

¿Alguien puede explicar lo que está pasando aquí?

que necesitaba usar el siguiente código torpe:

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

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

+0

Obtengo esto de la otra publicación: SqlDbType.SmallDateTime)) .Value = persona.Cumpleaños ?? (objeto) DBNull.Value; ¡Gracias! –

Respuesta

20

El problema es que DateTime? y DBNull.Value no son del mismo tipo por lo que no puede utilizar el operador coalescente nula en ellos.

En su caso se puede hacer person.Birthday ?? (object)DBNull.Value para pasar un valor de tipo object a través de Add()

3

Su primer problema es que para el operador ?? o ?:, los objetos de una u otra opción deben ser del mismo tipo. Aquí son de diferente tipo.

+1

Entonces, ¿qué hace '?:' Hacer? edit: no importa, lo sabía, nunca había visto esos 2 símbolos juntos antes. http://msdn.microsoft.com/en-us/library/ty67wk28.aspx –

3

prefiero iterar sobre mis parámetros justo antes de ejecutar la consulta, el cambio de todas las instancias de nula a DBNull según el caso, por ejemplo:

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

Esto me permite dejar los valores nulos como está y simplemente intercambiarlos en masa más tarde.

+0

Para mí esto es limpio y simple, buena respuesta. –

+0

Mi problema con esto es la sobrecarga adicional de iterar sobre los parámetros después del hecho, en lugar de manejarlos inmediatamente. – Andrew

Cuestiones relacionadas