LINQ генерирует условие избыточного IS NULL в SQL-заявлении

Я пишу некоторые LINQ для извлечения записей на основе электронной почты, однако сгенерированный SQL содержит дополнительное условие IS NULL которое не обязательно должно быть там, потому что я проверяю значение параметра для null в коде перед добавлением условия к запросу.

Мой код LINQ:

if (email != null)
{
    query = query.Where(r => r.Email == email);
}

Из этого условия SQL возникает следующее:

(([Extent1].[Email] = @p__linq__0) OR (([Extent1].[Email] IS NULL) AND (@p__linq__0 IS NULL)))

(([Extent1].[Email] IS NULL) AND (@p__linq__0 IS NULL))

не нужно быть там, насколько я вижу.

Есть ли способ заставить LINQ опустить его?

Ответ 1

Они там в случае, если email равна нулю.

Вы можете предотвратить это, установив UseDatabaseNullSemantics в true

Получает или задает значение, указывающее, будет ли отображаться нулевая семантика базы данных при сравнении двух операндов, обе из которых могут быть обнуляемы. Значение по умолчанию неверно. Например, (operand1 == operand2) будет переведен как: (operand1 = operand2), если UseDatabaseNullSemantics является истинным, соответственно (((operand1 = operand2) AND (NOT (операнд1 IS NULL ИЛИ операнд2 IS NULL))) ИЛИ ((операнд1 IS NULL) AND (операнд2 IS NULL))), если UseDatabaseNullSemantics является ложным.

Существуют различные способы применения этого.

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

using(TheContext dbContext = new TheContext()) {
    dbContext.Configuration.UseDatabaseNullSemantics = true;

    ...

    if (email != null)
    {
        query = query.Where(r => r.Email == email);
    }
}

Если вы хотите применить это ко всем запросам:

public class TheContext : DbContext
{
    public TheContext()
    {
        this.Configuration.UseDatabaseNullSemantics = true;
    }
}

Вы также можете изменить свойство как [Required]:

public class Model {
    [Required]
    public string Email { get; set; }
}