2009-07-14 5 views
11

J'ai une table avec une colonne qui a des valeurs nulles ... lorsque je tente d'interroger les enregistrements où cette colonne est NULL:LINQ to SQL - types nullables dans la clause where

cela fonctionne:



     var list = from mt in db.MY_TABLE 
        where mt.PARENT_KEY == null 
        select new { mt.NAME }; 

CELA NE:



     int? id = null; 
     var list = from mt in db.MY_TABLE 
        where mt.PARENT_KEY == id 
        select new { mt.NAME }; 

Pourquoi?

+1

Avez-vous essayé d'analyser le SQL généré dans chaque cas? Quel est le type de mt.PARENT_KEY? –

+0

la clé parent est un entier –

+0

Dans le code généré? Nullable , Nullable ? –

Répondre

20

après un peu plus googler, j'ai trouvé la réponse:

ref #1

ref #2

int? id = null; 
var list = from mt in db.MY_TABLE 
      where object.Equals(mt.PARENT_KEY, id) //use object.Equals for nullable field 
      select new { mt.NAME }; 

Ce LINQ est rendu à SQL comme suit:

((mt.PARENT_KEY IS NULL) AND (@id IS NULL)) 
OR ((mt.PARENT_KEY IS NOT NULL) AND (@id IS NOT NULL) AND (mt.PARENT_KEY = @id)) 
5

Une possibilité - si mt.PARENT_KEY est d'un autre type (par exemple long?) alors il y aura des conversions impliquées.

Il serait utile si vous pouviez montrer les types impliqués et la requête générée dans chaque cas.

EDIT: Je pense avoir une idée ...

Il pourrait être parce que # SQL et C ont des idées différentes de ce que l'égalité signifie quand il vient à null. Essayez ceci:

where (mt.PARENT_KEY == id) || (mt.PARENT_KEY == null && id == null) 

Si cette est le cas, alors il est un cas d'angle assez laid, mais je peux comprendre pourquoi il est fait de cette façon ... si le SQL généré est juste en utilisant

WHERE PARENT_KEY = @value 

alors cela ne fonctionnera pas lorsque la valeur est nulle - il a besoin:

WHERE (PARENT_KEY = @value) OR (PARENT_KEY IS NULL AND @value IS NULL) 

qui est ce que devrait générer cette dernière requête LINQ.


Sur intérêt, pourquoi la sélection avec

select new { mt.NAME } 

au lieu de simplement

select mt.NAME 

?) Pourquoi voudriez-vous une séquence de types anonymes au lieu d'une séquence de chaînes (ou quel que soit le type NAME est?

+0

J'ai mis à jour la réponse de Nick pour refléter comment Object.Equals rend SQL. À votre avis, le supplément '(mt.PARENT_KEY IS NOT NULL) ET (@id IS NOT NULL)' de la ligne 2 est-il superflu? Ceci est suggéré par votre réponse. (Plus de caractères de LINQ, moins de caractères de SQL) –

1

C'est certainement une question de C# et SQL ayant des notions de la façon de comparer les valeurs nulles - la question a été abordée ici avant:

Compare nullable types in Linq to Sql

+0

oui, mais cette solution est waaaayyyy trop compliquée –

Questions connexes