我对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
中过滤看起来很丑,不易阅读。
有更好的方法来重写这个吗?
答案 0 :(得分:4)
假设Status
是数值类型(例如int
或uint
或long
等),并且没有&
的自定义实现运算符&
使用其操作数执行按位AND 。
因此((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)))
这个更长,但如果名称是自我解释的话可能更具可读性。