Linq中的多个where或条件指向对象
本文关键字:条件 对象 where Linq | 更新日期: 2023-09-27 18:12:13
我有一个TelephoneDataType对象列表
public List<TelephoneDataType> Values { get; set; }
TelephoneDataType对象有一个名为ChartType的枚举属性
public class TelephoneDataType
{
public ChartType ChartId { get; set; }
}
因此,从这个值列表中,我想取出所有ChartId设置为以下值的TelephoneDataType对象:
回答被遗弃的ExpectedWaitInQueue
这是我失败的尝试
var items = telephoneData.Values
.Where(c => c.ChartId == Enums.ChartType.Answered)
.Where(c => c.ChartId == Enums.ChartType.Abandoned)
.Where(c => c.ChartId == Enums.ChartType.ExpectedWait)
.Where(c => c.ChartId == Enums.ChartType.InQueue).ToArray();
你目前的解决方案是在你的.Where
条款之间做&&
。您需要通过执行以下操作之一使它们成为||
的
var items = telephoneData.Values
.Where(c => c.ChartId == Enums.ChartType.Answered
|| c.ChartId == Enums.ChartType.Abandoned
|| c.ChartId == Enums.ChartType.ExpectedWait
|| c.ChartId == Enums.ChartType.InQueue
)
.ToArray();
或者
(更容易读,更容易更新/维护) var myFilterList = new []
{
Enums.ChartType.Answered,
Enums.ChartType.Abandoned,
Enums.ChartType.ExpectedWait,
Enums.ChartType.InQueue
};
var items = telephoneData.Values
.Where(c => myFilterList.Contains(c.ChartId)
.ToArray();
还要记住,您的.Where
子句不会立即执行。
它们只在执行.ToList
、.ToArray
等操作时执行。你可以在这里了解更多:https://msdn.microsoft.com/en-us/library/vstudio/bb738633(v=vs.100).aspx
我宁愿为Enums.ChartType
实现扩展方法,例如
public static class EnumsChartTypeExtensions {
//TODO: find out a proper name for the method
public static Boolean IsOnLine(this Enums.ChartType value) {
return value == Enums.ChartType.Answered ||
value == Enums.ChartType.Abandoned ||
value == Enums.ChartType.ExpectedWait ||
value == Enums.ChartType.InQueue;
}
}
那么你的Linq将会更容易读:
var items = telephoneData.Values
.Where(c => c.ChartId.IsOnLine())
.ToArray();
该解决方案的另一个优点是,如果你在Enums.ChartType
(例如WaitingForAnswer
)中添加一些状态,你所要做的就是只更新扩展方法(而不是整个应用程序中的所有Linq)
一步一步地思考你的查询。首先,您将获得ID为Answered
的所有图表。然后将该列表过滤为Abandoned
,但是条目都已经是Answered
了。
尝试使用or操作符。
var items = telephoneData.Values
.Where(c => c.ChartId == Enums.ChartType.Answered ||
c.ChartId == Enums.ChartType.Abandoned ||
c.ChartId == Enums.ChartType.ExpectedWait ||
c.ChartId == Enums.ChartType.InQueue).ToArray();
每个Where
返回一个过滤的可枚举对象,因此在您的第一个Where
之后,您只剩下一个ChartType
。您必须将这些条件组合成一个Where
操作,如下所示:
var items = (telephoneData.Values
.Where(c => c.ChartId == Enums.ChartType.Answered || c.ChartId == Enums.ChartType.Abandoned || c.ChartId == Enums.ChartType.ExpectedWait || c.ChartId == Enums.ChartType.InQueue)
.ToArray());
我认为最好的方法是为枚举编写一个特殊的扩展方法,这不仅可以帮助您处理这种情况:
public static class EnumExtensions
{
public static bool InSet<T>(this T target, params T[] possibleValues) where T : struct
{
return possibleValues.Contains(target);
}
}
解为:
var items = telephoneData.Values
.Where(c => c.ChartId.InSet(Enums.ChartType.Answered,
Enums.ChartType.Abandoned,
etc...);