2010-08-06 24 views
7

J'ai défini Classe Personne propriété Anniversaire as Nullable DateTime?, alors pourquoi l'opérateur de fusion null ne devrait-il pas fonctionner dans l'exemple suivant?C# ?? null opérateur de coalescence question

cmd.Parameters.Add(new SqlParameter("@Birthday", 
    SqlDbType.SmallDateTime)).Value =  
    person.Birthday ?? DBNull.Value; 

Le err du compilateur je suis arrivé était « Opérateur '??' ne peut pas être appliqué aux opérandes de type 'System.DateTime?' et « System.DBNull » »

Ce qui suit a également obtenu une erreur de compilation:

cmd.Parameters.Add(new SqlParameter("@Birthday", 
    SqlDbType.SmallDateTime)).Value = 
    (person.Birthday == null) ? person.Birthday:DBNull.Value; 

J'ai ajouté un casting à (objet) tel que recommandé par Refactor, et il a compilé, mais ne fonctionnait pas correctement et la valeur était stockée dans le sqlserver db comme nulle dans les deux cas.

SqlDbType.SmallDateTime)).Value =  
     person.Birthday ?? (object)DBNull.Value; 

Quelqu'un peut-il expliquer ce qui se passe ici?

je devais utiliser le code maladroit suivant:

if (person.Birthday == null) 
    cmd.Parameters.Add("@Birthday", SqlDbType.SmallDateTime).Value 
     = DBNull.Value; 
    else cmd.Parameters.Add("@Birthday", SqlDbType.SmallDateTime).Value = 
      person.Birthday; 
+3

Duplication de http://stackoverflow.com/questions/218808/c-ado-net-nulls-and-dbnull-is-there-more-efficient-syntax – sgriffinusa

+0

Vous avez obtenu ce message à partir de l'autre message: SqlDbType.SmallDateTime)) .Value = personne.Annaissance ?? (objet) DBNull.Value; Merci! –

Répondre

20

Le problème est que DateTime? et DBNull.Value ne sont pas le même type de sorte que vous ne pouvez pas utiliser l'opérateur coalescent nulle sur eux.

Dans votre cas, vous pouvez faire person.Birthday ?? (object)DBNull.Value passer une valeur de type object jusqu'à Add()

3

Votre premier problème est que pour l'opérateur ?? ou ?:, les objets pour soit le choix doit être du même type. Ici, ils sont de type différent.

+1

Alors qu'est-ce que '?:' Fais? edit: nevermind, je le savais, je n'ai jamais vu ces 2 symboles assemblés comme ça auparavant. http://msdn.microsoft.com/en-us/library/ty67wk28.aspx –

3

Je préfère parcourir mes paramètres avant d'exécuter la requête, la modification de tous les cas de nul à DBNull selon le cas, par exemple:

foreach (IDataParameter param in cmd.Parameters) 
    if (param.Value == null) 
     param.Value = DBNull.Value; 

Cela me permet de laisser des valeurs nulles en l'état et de les échanger simplement en masse plus tard.

+0

Pour moi, c'est propre et simple, bonne réponse. –

+0

Mon problème avec ceci est le surcoût supplémentaire d'itération sur les paramètres après le fait, par rapport à leur traitement immédiat. – Andrew