2008-10-20 10 views
47

Tengo un DateTime? que intento insertar en un campo usando DbParameter. Estoy creando el parámetro de este modo:C# ADO.NET: nulls y DbNull: ¿hay una sintaxis más eficiente?

DbParameter datePrm = updateStmt.CreateParameter(); 
datePrm.ParameterName = "@change_date"; 

y luego quiero poner el valor de la DateTime? en el dataPrm.Value mientras que la contabilidad de null s.

pensé inicialmente que sería inteligente:

datePrm.Value = nullableDate ?? DBNull.Value; 

pero que falla con el error

operador '??' no se puede aplicar a operandos del tipo 'System.DateTime?' y 'System.DBNull'

Así que supongo que eso solo funciona si el segundo argumento es una versión que no admite nulos del primer argumento. Entonces me fui para:

datePrm.Value = nullableDate.HasValue ? nullableDate.Value : DBNull.Value; 

pero que no funciona bien:

Tipo de expresión condicional no se puede determinar porque no hay una conversión implícita entre 'System.DateTime' y 'Sistema. DBNull '

Pero no quiero convertir entre esos tipos!

Hasta ahora la única cosa que puedo llegar al trabajo es:

if (nullableDate.HasValue) 
    datePrm.Value = nullableDate.Value; 
else 
    datePrm.Value = DBNull.Value; 

¿Es realmente la única forma que puede escribir esto? ¿Hay alguna manera de obtener un trazador de líneas utilizando el operador ternario para trabajar?

Actualización: Realmente no entiendo por qué el ?? la versión no funciona MSDN dice:

¿El ?? el operador devuelve el operando de la izquierda si no es nulo, o bien devuelve el operando derecho.

¡Eso es exactamente lo que quiero!

Update2: Bueno, era bastante obvio que al final:

datePrm.Value = nullableDate ?? (object)DBNull.Value; 
+0

http://stackoverflow.com/questions/1545711/is-it-possible-to-coalesce-string-and- dbnull-in-c – JohnB

Respuesta

61

Ah, ja! ¡Encontré una solución aún más eficiente que la de @ Trebz!

datePrm.Value = nullableDate ?? (object)DBNull.Value; 
+1

No lo llamaría más "eficiente", tal vez "conciso es una palabra mejor? –

+0

Derecho - usted sabe lo que quise decir. :-) –

+0

Esto es realmente genial! He estado buscando esto. Gracias – Brian

5

que iba a funcionar si se ha utilizado

datePrm.Value = nullableDate.HasValue ? (object)nullableDate.Value : DBNull.Value; 
+0

Sí, ese funciona bien, y tiene 8 caracteres menos que la solución de @ Dan. :-) Ojalá hubiera una manera de obtener el ?? solución para trabajar, ya que es una sintaxis mucho más corta. –

+0

Actualización: encontré una solución aún más eficiente usando ??. –

1

creo que el error con su segundo intento se debe a nullableDate .Value y DBNull.Value son tipos diferentes y el operador ternario necesita elegir un tipo para devolver en ambos casos.No tengo el entorno para probar esto, pero creo que esto debería funcionar para usted:

datePrm.Value = nullableDate.HasValue ? (object)nullableDate.Value : (object)DBNull.Value; 
0

La forma en que lo hago, es que tengo una clase de utilidad estática que sólo va a través y comprobaciones para ver si el el valor del parámetro es nulo, luego configuro el valor para hacer DBNull. Lo hago antes de llamar al Execute.

6

Si estás usando C# 3.0 puede crear un método de extensión para hacer esto fácil:

public static class DBNullableExtensions 
{ 
    public static object ToDBValue<T>(this Nullable<T> value) where T:struct 
    { 
     return value.HasValue ? (object)value.Value : DBNull.Value; 
    } 
} 


class Program 
{ 
    static void Main(string[] args) 
    { 
     int? x = null; 

     Console.WriteLine( x.ToDBValue() == DBNull.Value); 
    } 
} 
5

Si está utilizando SQL Server, el espacio de nombres System.Data.SqlTypes contiene algunas clases de utilidad que evitan la conversión de tipo molesto. Por ejemplo, en lugar de esto:

var val = (object) "abc" ?? DBNull.Value; 

se puede escribir esto:

var val = "abc" ?? SqlString.Null; 
+0

+1 @La respuesta de Marco Gherardi es ideal. Todavía puede usar el operador ternario, solo use las clases auxiliares proporcionadas por System.Data.SqlTypes –

Cuestiones relacionadas