В чем разница между & и && в EF Core

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

Если вам это нужно для ef (Core или нет), и вам нужны условия, я бы посоветовал всегда использовать && или ||. Потому что побитовые операторы в данный момент вам не знакомы.

Nikolaus 20.02.2019 09:35
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
1 353
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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

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

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

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

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

Для целочисленных типов оператор & вычисляет логические побитовые 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 Core, @Ivan Stoev подробно объяснил это:Здесь

Спасибо @TanvirArjel, вопрос о поведении EF.

Kamran 20.02.2019 09:37
Ответ принят как подходящий

but what about EF? Is there any differences between & and && (same for | and ||)? performance-wise!

Да, есть.

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

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

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

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

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

Здорово! Но не понял эту строчку so it can't be short-circuited.

TanvirArjel 20.02.2019 09:50

@TanvirArjel Я имел в виду, что при выполнении на стороне клиента используются те же правила оценки, что и в соответствующем коде C#. например && и || замкнет накоротко, & и | — нет.

Ivan Stoev 20.02.2019 09:58

Я понял это! но в случае сервера sql expr1 AND expr2 ведет себя не так, как C# expr1 && expr2? или что-нибудь еще.

TanvirArjel 20.02.2019 10:00

@TanvirArjel Часть короткое замыкание имеет значение для оценка клиента. Для оценка сервера разница заключается в переводе SQL, что, скорее всего, повлияет на производительность из-за неестественных WHERE условий.

Ivan Stoev 20.02.2019 10:09

Мой вопрос: в случае expr1 AND expr2 на SQL-сервере, если первый операнд ложен, будет оцениваться второй операнд или нет?

TanvirArjel 20.02.2019 10:11

@TanvirArjel Способ оценки запроса зависит от оптимизаторов запросов к базе данных и создаваемых ими планов выполнения запросов. Им разрешено делать многое - переупорядочивать условия (чтобы использовать индекс) и т. д., поэтому в целом на ваш вопрос нельзя ответить.

Ivan Stoev 20.02.2019 10:15

Я в одном шаге от того, чтобы проголосовать за ваш ответ :) Другой вопрос: в случае (expr1 & expr2) = 1 на SQL-сервере, какое влияние это окажет на запрос, я не уверен в этом?

TanvirArjel 20.02.2019 10:18

@TanvirArjel Опять же, неизвестно, как перевод SQL влияет на план запроса. SqlServer может быть умным и относиться к нему как к AND, а может и нет. И у Oracle, например, определенно будут проблемы как с переводом, так и с выполнением. Дело в том, что AND и OR — это способы естественный представления бинарных логических условий внутри предикатов SQL. Идея SQL состоит в том, чтобы описать желаемый результат, а не как для этого. Что отличается от LINQ to Objects, где выполнение зависит от того, как вы составляете запрос.

Ivan Stoev 20.02.2019 10:27

Хорошо! Большое спасибо, я буду экспериментировать с этим на уровне SQL-сервера.

TanvirArjel 20.02.2019 10:30

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

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.

Всем спасибо!

Другие вопросы по теме