2009-07-14 2 views
11

У меня есть таблица со столбцом, который имеет нулевые значения ... когда я пытаюсь запрос для записей, где этот столбец NULL:LINQ к SQL - обнуляемых типы в котором положение

ЭТО РАБОТАЕТ:



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

эТО НЕ:



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

Почему?

+1

Вы пробовали смотреть на SQL, сгенерированный в каждом случае? Какой тип mt.PARENT_KEY? –

+0

родительский ключ является целым числом –

+0

В сгенерированном коде? Nullable , Nullable ? –

ответ

20

после некоторых более прибегая к помощи, я нашел ответ:

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

Этот LINQ отображает SQL следующим образом:

((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

Одна возможность - если mt.PARENT_KEY имеет какой-либо другой тип (например, long?), тогда будут задействованы преобразования.

Это поможет, если вы можете показать задействованные типы и запрос, сгенерированный в каждом случае.

EDIT: Я думаю, что у меня есть идея ...

Это может быть потому, что SQL и C# имеют разные представления о том, что означает равенство, когда дело доходит до обнулить. Попробуйте это:

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

Если является так, то это очень некрасиво угол так, но я могу понять, почему это сделано именно так ... если сгенерированный SQL просто использует

WHERE PARENT_KEY = @value 

то, что не будет работать, если значение равно нулю - это необходимо:

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

, который является то, что последний запрос LINQ должен генерировать.


Из интереса, почему вы выбор с

select new { mt.NAME } 

вместо просто

select mt.NAME 

?) Почему вы хотите, последовательность анонимных типов вместо последовательности строк (или какой-либо тип NAME?

+0

Я обновил ответ Ника, чтобы отразить, как Object.Equals отображает SQL. На ваш взгляд, лишний '(mt.PARENT_KEY IS NOT NULL) И (@id IS NOT NULL)' в строке 2 лишний? Это предлагается вашим ответом. (Больше символов LINQ, меньше символов SQL) –

1

Это определенно вопрос C# и SQL, имеющие разные представления о том, как сравнивать аннулирует - вопрос был адресован здесь раньше:

Compare nullable types in Linq to Sql

+0

да, но это решение waaaayyyy слишком сложно –

Смежные вопросы