Question

J'ai un DateTime? que j'essaie d'insérer dans un champ à l'aide d'un DbParameter . Je crée le paramètre comme suit:

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

Et ensuite, je veux mettre la valeur du DateTime? dans le dataPrm.Value tout en tenant compte des null s.

Je pensais au départ que je serais malin:

datePrm.Value = nullableDate ?? DBNull.Value;

mais cela échoue avec l'erreur

  

Opérateur '??' ne peut pas être appliqué à des opérandes de type 'System.DateTime?' et 'System.DBNull'

Donc, je suppose que cela ne fonctionne que si le deuxième argument est une version non Nullable du premier argument. Alors je suis allé chercher:

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

mais cela ne fonctionne pas non plus:

  

Le type de l'expression conditionnelle ne peut pas être déterminé car il n'y a pas de conversion implicite entre 'System.DateTime' et 'System.DBNull'

Mais je ne veux pas convertir entre ces types!

Jusqu'à présent, la seule chose que je peux faire pour travailler est:

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

Est-ce vraiment la seule façon pour moi d'écrire ceci? Existe-t-il un moyen de faire fonctionner un one-line en utilisant l'opérateur ternaire?

Mise à jour: Je ne comprends pas vraiment pourquoi ?? la version ne fonctionne pas. MSDN dit:

  

Le ?? L'opérateur renvoie l'opérande de gauche s'il n'est pas nul ou renvoie l'opérande de droite.

C'est exactement ce que je veux!

Update2: En fin de compte, c'était plutôt évident:

datePrm.Value = nullableDate ?? (object)DBNull.Value;
Était-ce utile?

La solution

Ah ah! J'ai trouvé une solution encore plus efficace que celle de @ Trebz!

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

Autres conseils

Si vous utilisez SQLServer, l’espace de noms System.Data.SqlTypes contient des classes d’utilitaires qui évitent les transtypages gênants. Par exemple au lieu de ceci:

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

vous pouvez écrire ceci:

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

Cela fonctionnerait si vous utilisiez

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

Si vous utilisez C # 3.0, vous pouvez créer une méthode d'extension simple:

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

Je pense que l'erreur lors de votre deuxième tentative est due aux types différents nullableDate.Value et DBNull.Value et à l'opérateur ternaire devant choisir un type à renvoyer dans les deux cas. Je n'ai pas l'environnement pour tester cela, mais je pense que cela devrait fonctionner pour vous:

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

Comme je le fais, j’ai une classe d’utilitaire statique qui vérifie si le paramètre a la valeur null, puis j’ai défini la valeur sur DBNull. Je fais juste ça avant d’appeler Execute.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top