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中的过滤器看起来很难看,不容易阅读。

有更好的重写方法吗?

Linq Where语句的更好写法

假设Status是数值类型(如intuintlong等)并且没有自定义实现&操作符,&对其操作数执行位与

所以((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)))

这个比较长,但是如果名字是自解释的,可能会更容易读懂。