Linq Where语句的更好写法
本文关键字:更好 Where 语句 Linq | 更新日期: 2023-09-27 18:04:36
我对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
中的过滤器看起来很难看,不容易阅读。
有更好的重写方法吗?
假设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)
但这只是一个简化…可读性在于读者的眼睛。对于Status
字段,使用enum
可能更合适:
[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)))
这个比较长,但是如果名字是自解释的,可能会更容易读懂。