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 ceci:
DbParameter datePrm = updateStmt.CreateParameter();
datePrm.ParameterName = "@change_date";
Et puis je veux mettre la valeur du DateTime?
dans le dataPrm.Value
tout en tenant compte de null
s.
Je pensais au départ que je serais intelligent:
datePrm.Value = nullableDate ?? DBNull.Value;
mais cela échoue avec l'erreur
Opérateur '??' ne peut pas être appliqué aux opérandes de type 'System.DateTime?' et 'System.DBNull'
Je suppose donc 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 ça ne marche pas non plus:
Le type d'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 puisse obtenir au travail est:
if (nullableDate.HasValue)
datePrm.Value = nullableDate.Value;
else
datePrm.Value = DBNull.Value;
Est-ce vraiment la seule façon d'écrire ça? Existe-t-il un moyen d'obtenir un one-liner en utilisant l'opérateur ternaire pour travailler?
pdate: 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, sinon il renvoie l'opérande de droite.
C'est exactement ce que je veux!
pdate2: Eh bien, c'était un peu évident à la fin:
datePrm.Value = nullableDate ?? (object)DBNull.Value;
Ah ha! J'ai trouvé une solution encore plus efficace que celle de @ Trebz!
datePrm.Value = nullableDate ?? (object)DBNull.Value;
Si vous utilisez SQLServer, le System.Data.SqlTypes
l'espace de noms contient quelques classes utilitaires qui évitent le transtypage de type ennuyeux. Par exemple, au lieu de cela:
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 pour le faire facilement:
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 avec votre deuxième tentative est due à nullableDate.Value et DBNull.Value étant des types différents et à l'opérateur ternaire ayant besoin de choisir un type à retourner 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;
La façon dont je le fais, c'est que j'ai une classe d'utilité statique qui passe juste en revue et vérifie si la valeur du paramètre est nulle, puis je définis la valeur pour faire DBNull. Je fais juste ça avant d'appeler l'Execute.