В чем разница между & и && в EF Core - PullRequest
0 голосов
/ 20 февраля 2019

Я понимаю, что && закорачивает оценку, поэтому не нужно оценивать RHS, если нет, но как насчет EF?Есть ли различия между & и && (то же самое для | и ||)?производительность мудрый!

Ответы [ 3 ]

0 голосов
/ 20 февраля 2019

а как же EF?Есть ли различия между & и && (то же самое для | и ||)?с точки зрения производительности!

Да, есть.

Во-первых, иногда EF Core использует оценку клиента , поэтому она не может быть закорочена.

Во-вторых, даже при использовании оценки сервера EF Core переводит их по-разному.Например, вот перевод для SqlServer:

LINQ             SQL
==============   ============ 
expr1 && expr2   expr1 AND expr2
expr1 & expr2    (expr1 & expr2) = 1

То, влияет ли это на производительность, зависит от оптимизатора запросов к базе данных, но первый выглядит в целом лучше.А некоторые провайдеры баз данных, у которых нет встроенной поддержки типа bool, могут генерировать довольно неэффективный перевод или даже не могут переводить предикаты & / |.

Короче, желательно всегда использовать логические операторы && и || в запросах LINQ.

0 голосов
/ 20 февраля 2019

Я решил провести эксперимент:

var t1 = _db.Customers
.Where(x => x.FirstName == "james" | x.FirstName == "thomas")
.Select(x=>x.CustomerId).ToList();

против

var t2 = _db.Customers
.Where(x => x.FirstName == "james" || x.FirstName == "thomas")
.Select(x => x.CustomerId).ToList();

t1 был выполнен как:

SELECT [x].[CustomerId]
FROM [Customers] AS [x]
WHERE (CASE
    WHEN [x].[FirstName] = N'james'
    THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
END | CASE
    WHEN [x].[FirstName] = N'thomas'
    THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
END) = 1

и t2 как:

SELECT [x].[CustomerId]
FROM [Customers] AS [x]
WHERE [x].[FirstName] IN (N'james', N'thomas')

Оба возвращают одинаковый результат.Я сравнил их план выполнения, для выполнения t1 у меня было «Сканирование индекса», в то время как для выполнения t2 у меня был «Поиск индекса».Как упоминал Джастин ( Планы SQL Server: разница между сканированием индекса и поиском индекса ) «Поиск всегда лучше, чем сканирование, поскольку он более эффективен в способе поиска данных».

Итак, используя |или & не только это может привести к оценке на стороне клиента, но и к сгенерированному sql.

Спасибо всем!

0 голосов
/ 20 февраля 2019

Согласно документации Microsoft:

1. & Operator поддерживается в двух формах: унарный оператор с адресом или двоичный логическийoperator.

Унарный адрес оператора:

Унарный оператор & возвращает адрес своего операнда.Для получения дополнительной информации см. Как: получить адрес переменной .Оператор адреса & требует небезопасного контекста.

Целочисленный логический побитовый оператор И:

Для целочисленных типов оператор & вычисляет логический побитовый код AND его операндов:

uint a = 0b_1111_1000;
uint b = 0b_1001_1111;
uint c = a & b;
Console.WriteLine(Convert.ToString(c, toBase: 2));
// Output:
// 10011000

2. Оператор && является условным логическим оператором И, также известным как оператор «короткого замыкания» логического И, вычисляет логическое Иего булевых операндов.Результат x && y истинен, если оба значения x и y равны true.В противном случае результат равен false.Если первый операнд оценивается как false, второй операнд не оценивается, а результат операции равен false. Следующий пример демонстрирует такое поведение:

bool SecondOperand()
{
    Console.WriteLine("Second operand is evaluated.");
    return true;
}

bool a = false && SecondOperand(); // <-- second operand is not evaluated here
Console.WriteLine(a);
// Output:
// False

bool b = true && SecondOperand(); // <-- second operand is evaluated here
Console.WriteLine(b);
// Output:
// Second operand is evaluated.
// True

Теперь в случае EF/ EF Базовое поведение @Иван Стоев объяснил это очень сильно: Здесь

...