Linq, где column == (нулевая ссылка) не совпадает с столбцом == null

Я столкнулся с довольно странной проблемой с linq-to-sql. В следующем примере

var survey = (from s in dbContext.crmc_Surveys
                                   where (s.crmc_Retail_Trade_Id == tradeId) && (s.State_.Equals(state))
                                   select s).First();

Если tradeId имеет значение NULL, он не ведет себя так, как если бы я указал null именно таким образом,

var survey = (from s in dbContext.crmc_Surveys
                                   where (s.crmc_Retail_Trade_Id == null) && (s.State_.Equals(state))
                                   select s).First();

Это мое желаемое поведение. На самом деле он ничего не возвращает, если оба значения не равны нулю. Я не могу понять, как выполнить это несколько различных запросов linq. Любые идеи?

Ответ 1

Измените where (s.crmc_Retail_Trade_Id == tradeId) до

where (s.crmc_Retail_Trade_Id == tradeId || 
      (tradeId == null && s.crmc_Retail_Trade_Id == null))

Изменить - на основе этот пост от Brant Lamborn, похоже, что следующее будет делать то, что вы хотите:

where (object.Equals(s.crmc_Retail_Trade_Id, tradeId))

Null Semantics (LINQ to SQL) Страница MSDN ссылается на некоторую интересную информацию:

LINQ to SQL не налагает С# null или Visual Basic ничего сравнения семантика SQL. Операторы сравнения синтаксически переведены на их SQL-эквиваленты. Семантика отражает SQL-семантика, определенная сервером или Настройки соединения. Два нулевых значения считаются неравными по умолчанию SQL Server (хотя вы можете измените настройки, чтобы изменить семантика). Несмотря на это, LINQ to SQL не учитывает настройки сервера в перевод запросов.

Сравнение с буквальным нулем (ничего) переводится на соответствующая версия SQL (имеет значение null или не ноль).

Значение null (ничего) в сортировка определяется SQL Server; LINQ to SQL не изменяет сверка.

Ответ 2

Не уверен в этом, но я подозреваю, что когда linq-to-sql переводит это в строку запроса sql, вы получаете немного другое выражение, определяющее null напрямую, так что в какой-то момент вы в конечном итоге сравниваете NULL с самим собой и NULL = NULL определяется как false.

Ответ 3

Еще одна возможность решить эту проблему, так как я столкнулся с этой проблемой.

where (tradeId == null ? s.crmc_Retail_Trade_Id == null : s.crmc_Retail_Trade_Id == tradeId)

Ответ 4

Я не знаком с Linq, однако вообще:

NULL представляет отсутствующее, неизвестное или undefined значение. Строго говоря, переменная не может равняться NULL; низкоуровневые языки, которые обеспечивают эту конструкцию, обычно делают это как удобство, потому что нет простой альтернативы - на более высоком уровне обычно лучше полагаться на ISNULL, defined или на любые функции, которые предоставляет ваш язык.

Одна переменная undefined не равна другой переменной undefined (и то же самое относится к NULL == NULL). Joe Celko имеет хороший пример написания запроса, чтобы найти всех людей, цвет волос которых соответствует цвету автомобиля, которым они управляют. Должен ли этот запрос соответствовать лысому человеку, который ходит везде?