Многократное использование || и && операнды

У меня есть запрос с использованием Entity Framework. У него много разных операндов, и я смущен его приоритетом. Я получаю неправильный результат. Мне нужны все записи, которые IsPaid == true или IsPaid == null, также все записи должны быть TypeId == 1 или TypeId == 2, также должны быть CityId == 1 и CategoryId == 2. По какой-то причине он не оценивает CityId и CategoryId. Что я делаю не так? Спасибо.

var list = db.Ads.Where (x =>
               x.IsPaid == true || x.IsPaid == null &&
               x.TypeId == 1 || x.TypeId == 2 &&
               x.CityId == 1 && x.CategoryId == 2
).ToList();

Ответы

Ответ 1

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

(x.IsPaid == true || x.IsPaid == null) && (x.TypeId == 1 || x.TypeId == 2) && x.CityId == 1 && x.CategoryId == 2


&& имеет более высокое происхождение, чем ||

Так false && false || true false && false || true будет переведено в (false && false) || true (false && false) || true => true


Sidenote как упомянуто @Joey:

Вместо (x.IsPaid == true || x.IsPaid == null) вы можете написать (x.IsPaid != false).

Ответ 2

Из-за приоритет оператора, && привязывается выше ||.

Если вы связываете инструкции Where, то более ясно, что происходит:

var list = db.Ads
          .Where(x => x.IsPaid == true || x.IsPaid == null)
          .Where(x=> x.TypeId == 1 || x.TypeId == 2)
          .Where(x=> x.CityId == 1)
          .Where(x=> x.CategoryId == 2)
          .ToList();

Ответ 3

&& имеет более высокий приоритет, чем ||, как и в математике. Итак, эффективно ваше условие следующее:

x.IsPaid == true ||
x.IsPaid == null && x.TypeId == 1 ||
x.TypeId == 2 && x.CityId == 1 && x.CategoryId == 2

Если любое из этих выражений на отдельных строках истинно, все выражение истинно. Вы должны использовать круглые скобки для пояснения здесь:

(x.IsPaid == true || x.IsPaid == null) &&
(x.TypeId == 1 || x.TypeId == 2) &&
 x.CityId == 1 &&
 x.CategoryId == 2

Ответ 4

Попробуйте следующее:

var list = db.Ads.Where (
            (x => x.IsPaid == true || x.IsPaid == null) && 
            (x.TypeId == 1 || x.TypeId == 2) && 
            (x.CityId == 1 && x.CategoryId == 2)
).ToList();