Лучший способ написать заявление Linq Where
Я запутался насчет нескольких фильтров Linq
запрос.
Как это:
var OrderList = (from o in db.Order
where ( o.OrderType == 1 &&
(( (o.Status & 1) != 0) || ((o.Status & 2) != 0)) )
|| ( o.OrderType == 2 &&
(( (o.Status & 3) != 0) || ((o.Status & 4) != 0)) )
orderby o.OrderID descending
select new
{
Name = o.Name
}).ToList();
Фильтровать в Linq
выглядит некрасиво и не легко читается.
Есть лучший способ переписать это?
1 ответ
При условии, что Status
тип числового значения (например, int
или же uint
или же long
и т. д.) и не имеет собственной реализации &
оператор, &
выполняет побитовое И со своими операндами.
Так ((o.Status & 1) != 0) || ((o.Status & 2) != 0)
такой же как (o.Status & 3) != 0
, Он только проверяет, установлен ли хотя бы один из двух младших значащих битов. (Обратите внимание, что биты 3
являются 0011
).
Соответственно (o.Status & 3) != 0) || (o.Status & 4) != 0
такой же как (o.Status & 7) != 0
(биты 7
являются 0111
).
Таким образом, вы можете упростить условие до этого:
(o.OrderType == 1 && (o.Status & 3) != 0) ||
(o.OrderType == 2 && (o.Status & 7) != 0)
Но это только упрощение... Читаемость лежит в глазах читателя. Может быть целесообразно использовать enum
для Status
поле вместо:
[Flags]
public enum States
{
FirstBit = 1, // use self-explaining names here
SecondBit = 2,
ThirdBit = 4
}
// condition
(o.OrderType == 1 && (o.Status.HasFlag(States.FirstBit) || o.Status.HasFlag(States.SecondBit)) ||
(o.OrderType == 2 && (o.Status.HasFlag(States.FirstBit) || o.Status.HasFlag(States.SecondBit) || o.Status.HasFlag(States.ThirdBit)))
Это длиннее, но может быть более читабельным, если названия говорят сами за себя.