Вопрос по linq-to-sql – LINQ to SQL - обнуляемые типы в предложении where

11

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

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



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

Зачем?

Вы пробовали смотреть на SQL, сгенерированный в каждом случае? Какой тип mt.PARENT_KEY? Jon Skeet
В сгенерированном коде? Nullable & lt; int & gt ;, Nullable & lt; long & gt ;? Jon Skeet
родительский ключ является целым числом Nick Franceschina

Ваш Ответ

3   ответа
5

mt.PARENT_KEY имеет некоторый другой тип (например,long?) тогда будут конверсии.

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

РЕДАКТИРОВАТЬ: Я думаю, у меня есть идея ...

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

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

Если этоis в таком случае это довольно уродливый угловой случай, но я могу понять, почему это так ... если сгенерированный 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 является?

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

ссылка № 1

ссылка № 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 };

This LINQ renders to SQL as follows:

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

имеющих разные представления о том, как сравнивать нули - этот вопрос уже рассматривался здесь ранее:

Сравните обнуляемые типы в Linq и Sql

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

Похожие вопросы