Pregunta

Tengo un DateTime? que estoy tratando de insertar en un campo usando un DbParameter . Estoy creando el parámetro así:

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

Y luego quiero poner el valor de DateTime? en el dataPrm.Value mientras se tienen en cuenta null s.

Al principio pensé que sería inteligente:

datePrm.Value = nullableDate ?? DBNull.Value;

pero eso falla con el error

  

Operador '??' no se puede aplicar a los operandos de tipo 'System.DateTime?' y 'System.DBNull'

Supongo que eso solo funciona si el segundo argumento es una versión no anulable del primer argumento. Entonces fui por:

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

pero eso tampoco funciona:

  

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

¡Pero no quiero convertir entre esos tipos!

Hasta ahora, lo único que puedo hacer para trabajar es:

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

¿Es esa realmente la única forma en que puedo escribir esto? ¿Hay alguna manera de conseguir que funcione una sola línea utilizando el operador ternario?

Actualización: ¿Realmente no entiendo por qué? La versión no funciona. MSDN dice:

  

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

¡Eso es exactamente lo que quiero!

Update2: Bueno, al final resultó bastante obvio:

datePrm.Value = nullableDate ?? (object)DBNull.Value;
¿Fue útil?

Solución

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

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

Otros consejos

Si está utilizando SQLServer, 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;

puedes escribir esto:

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

Funcionaría si usas

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

Si está utilizando C # 3.0, puede crear un método de extensión para hacer esto fácilmente:

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 );
    }
}

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

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

La forma en que lo hago, es que tengo una clase de utilidad estática que simplemente pasa y comprueba si el valor del parámetro es nulo, luego establezco el valor para hacer DBNull. Solo hago eso antes de llamar al Ejecutar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top