我有一个名为OrderStatus
的枚举,它包含订单可以使用的各种状态:
我想要做的是创建一个LINQ语句,告诉我OrderStaus是有效,有效,已处理还是已完成。
现在我有类似的东西:
var status in Order.Status.WHERE(status =>
status.OrderStatus == OrderStatus.Valid ||
status.OrderStatus == OrderStatus.Active||
status.OrderStatus == OrderStatus.Processed||
status.OrderStatus == OrderStatus.Completed)
这有效,但它非常“罗嗦”。有没有办法将其转换为Contains()
语句并将其缩短一点?
答案 0 :(得分:16)
不确定
var status in Order.Status.Where(status => new [] {
OrderStatus.Valid,
OrderStatus.Active,
OrderStatus.Processed,
OrderStatus.Completed
}.Contains(status.OrderStatus));
您还可以定义一个接受对象和params数组的扩展方法In()
,并基本上包装Contains函数:
public static bool In<T>(this T theObject, params T[] collection)
{
return collection.Contains(theObject);
}
这允许您以更多SQL-ish方式指定条件:
var status in Order.Status.Where(status =>
status.OrderCode.In(
OrderStatus.Valid,
OrderStatus.Active,
OrderStatus.Processed,
OrderStatus.Completed));
了解并非所有Linq提供商都喜欢他们的lambda中的自定义扩展方法。例如,NHibernate将无法正确转换In()函数而无需额外编码来扩展表达式解析器,但Contains()可以正常工作。对于Linq 2对象,没问题。
答案 1 :(得分:2)
我使用过这个扩展程序:
public static bool IsIn<T>(this T value, params T[] list)
{
return list.Contains(value);
}
您可以将此作为条件:
Where(x => x.IsIn(OrderStatus.Valid, ... )
答案 2 :(得分:1)
如果这组状态具有某些含义,例如那些是接受订单的状态,您可以在枚举上定义扩展方法并在linq查询中使用它。
public static class OrderStatusExtensions
{
public static bool IsAccepted(this OrderStatuses status)
{
return status == OrderStatuses.Valid
|| status == OrderStatuses.Active
|| status == OrderStatuses.Processed
|| status == OrderStatuses.Completed;
}
}
var acceptedOrders = from o in orders
where o.Status.IsAccepted()
select o;
即使你不能给这个方法一个简单的名字,你仍然可以使用IsValidThroughCompleted
之类的东西。在任何一种情况下,它似乎都以这种方式表达了更多的含义。
答案 3 :(得分:0)
根据您在问题中指定的顺序来定义枚举,您可以通过使用整数比较来缩短它。
var result =
Order.Status.Where(x =>
(int)x >= (int)OrderStatus.Valid &
& (int)x <= (int)OrderStatus.Completed);
这种比较虽然可以被认为是片状的。简单地重新排序枚举值会默默地破坏这种比较。我宁愿坚持使用更多罗嗦的版本,也可能通过将比较重构为单独的方法来清理它。
答案 4 :(得分:0)
您可以将它们放入集合中,然后使用:
OrderStatus searchStatus = new[] {
OrderStatus.Valid,
OrderStatus.Active,
OrderStatus.Processed,
OrderStatus.Completed };
var results = Order.Status.Where(status => searchStatus.Contains(status));