48 votes

C # ADO.NET: nulls et DbNull - existe-t-il une syntaxe plus efficace?

J'ai un DateTime? que j'essaie de l'insérer dans un champ à l'aide d'un DbParameter. Je suis de la création du paramètre, comme ceci:

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

Et puis je veux mettre la valeur de l' DateTime? dans la dataPrm.Value lors de la comptabilité pour nulls.

Je pensais au départ, je serais intelligent:

datePrm.Value = nullableDate ?? DBNull.Value;

mais qui échoue avec l'erreur

L'opérateur '??' ne peut pas être appliquée à des opérandes de type 'System.DateTime?' et 'Système.DBNull'

Donc je suppose que cela ne fonctionne que si le second argument est un non nullable version du premier argument. Alors je suis allé pour:

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

mais cela ne fonctionne pas, soit:

Type de l'expression conditionnelle ne peut pas être déterminé, car il n'y a pas de conversion implicite entre "Système".DateTime' et 'Système.DBNull'

Mais je ne veux pas convertir entre ces types!

Jusqu'à présent, la seule chose que je peux l'obtenir pour fonctionner est de:

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

Est-ce vraiment la seule façon que je peux écrire ceci? Est-il possible d'obtenir un one-liner à l'aide de l'opérateur ternaire de travail?

Mise à jour: je ne comprends pas trop pourquoi ?? la version ne fonctionne pas. MSDN dit:

L' ?? l'opérateur renvoie la gauche opérande si elle n'est pas null, sinon elle renvoie l'opérande de droite.

C'est exactement ce que je veux!

Update2: eh Bien, c'était une sorte d'évidence à la fin:

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

62voto

Stewart Johnson Points 7632

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

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

5voto

Pop Catalin Points 25033

Si vous utilisez C # 3.0, vous pouvez créer une méthode d’extension facile à effectuer:

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

5voto

dnolan Points 1442

Cela fonctionnerait si vous utilisiez

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

1voto

Dan Points 1404

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 sélectionner 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;
 

0voto

Darren Kopp Points 27704

La façon dont je le fais, c’est que j’ai une classe d’utilitaire statique qui passe au travers et vérifie si le paramètre a la valeur null, puis j’ai défini la valeur pour faire DBNull. Je fais juste cela avant que j'appelle l'exécution.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X