Я хочу выполнить такой запрос
var result = from entry in table
where entry.something == null
select entry;
и получить сгенерированное IS NULL
.
Отредактировано: после первых двух ответов я чувствую необходимость уточнить, что я использую Entity Framework, а не Linq to SQL. Метод object.Equals (), похоже, не работает в EF.
Изменить № 2: вышеупомянутый запрос работает как задумано. Это правильно генерирует IS NULL
. Мой производственный код однако был
value = null;
var result = from entry in table
where entry.something == value
select entry;
и сгенерированный SQL был something = @p; @p = NULL
. Кажется, что EF правильно переводит константное выражение, но если переменная задействована, она обрабатывает его как обычное сравнение. Имеет смысл на самом деле. Я закрою этот вопрос
Обходной путь для Linq-to-SQL:
var result = from entry in table
where entry.something.Equals(value)
select entry;
Обходной путь для Linq-to-Entities (ой!):
var result = from entry in table
where (value == null ? entry.something == null : entry.something == value)
select entry;
Это неприятная ошибка, которая укусила меня несколько раз. Если эта ошибка также повлияла на вас, посетите отчет об ошибке на UserVoice и сообщите Microsoft, что эта ошибка также повлияла на вас.
Редактировать: эта ошибка исправлена в EF 4.5 ! Спасибо всем за то, что проголосовали за эту ошибку!
Для обратной совместимости это будет опцией - вам нужно вручную включить настройку, чтобы значение entry == value
работало. Пока нет слов о том, что это за настройка. Оставайтесь в курсе!
Редактировать 2: Согласно этому сообщению команды EF, эта проблема была исправлена в EF6! Woohoo!
Мы изменили поведение EF6 по умолчанию, чтобы компенсировать трехзначную логику.
Это означает, что существующий код, который опирается на старое поведение ( null != null
, но только при сравнении с переменной) , необходимо либо изменить, чтобы не полагаться на это поведение, либо установить для UseCSharpNullComparisonBehavior
значение false, чтобы использовать старое неработающее поведение.
Начиная с Entity Framework 5.0, вы можете использовать следующий код для решения вашей проблемы:
public abstract class YourContext : DbContext
{
public YourContext()
{
(this as IObjectContextAdapter).ObjectContext.ContextOptions.UseCSharpNullComparisonBehavior = true;
}
}
Это должно решить ваши проблемы, так как Entity Framerwork будет использовать 'C # like' нулевое сравнение.