Многократное использование || и && операнды
У меня есть запрос с использованием 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();