C# LINQ查询检查一个集合是否包含两个具有特定值的记录?
我正在寻找一个仅当一组数据至少有一条记录的状态为C# LINQ查询检查一个集合是否包含两个具有特定值的记录?,c#,linq,C#,Linq,我正在寻找一个仅当一组数据至少有一条记录的状态为State==0和另一条记录的状态为State>0时才返回true的查询 我有这个方法: public bool HasHistory(Guid id) { return GetHistory(id).Any(x => x.State == 0); //&&x.State > 0 ?! } 我不知道如何做到这一点,因为大多数LINQ扩展方法都会分别迭代每个元素
State==0
和另一条记录的状态为State>0
时才返回true的查询
我有这个方法:
public bool HasHistory(Guid id)
{
return GetHistory(id).Any(x => x.State == 0); //&&x.State > 0 ?!
}
我不知道如何做到这一点,因为大多数LINQ扩展方法都会分别迭代每个元素 只需使用
&&
-运算符组合不同查询的结果:
public bool HasHistory(Guid id)
{
var hist = GetHistory(id);
return hist.Any(x => x.State == 0) && hist.Any(x => x.State > 0);
}
这个怎么了
public bool HasHistory(Guid id)
{
var history = GetHistory(id);
return history.Any(x => x.State == 0) && history.Any(x => x.State > 0);
}
实际上,如果您使用的是大数据,那就不好了,因为您要枚举集合2次而不是1次。否则,只需使用此解决方案。您可以使用
聚合
方法:
public bool HasHistory( Guid id )
{
var history = GetHistory( id );
var check1 = false;
var check2 = false;
return history.Any( x =>
{
check1 = check1 || x.State == 0;
check2 = check2 || x.State > 0;
return check1 && check2;
} );
}
public bool HasHistory(Guid id)
{
var result = GetHistory(id)
.Aggregate(new { stateIsZero = true, stateIsPositive = true, hasItems = false },
(a, x) => new
{
stateIsZero = a.stateIsZero && x.State == 0,
stateIsPositive = a.stateIsPositive && x.State > 0,
hasItems = true
});
return result.stateIsZero && result.stateIsPositive && result.hasItems;
}
但是这种方法不适用于
IQueryable
“分别迭代每个元素”,问题出在哪里?您需要检查一个元素是否满足条件一。然后检查是否有任何对象满足条件2。这可以通过逐个迭代对象来完成。如果您关心效率,只需使用foreach迭代GetHistory
,然后只需一次枚举即可解决。这并不是说foreach在某种程度上被LINQ淘汰了。@Evk如果GetHistory()
返回一个IQueryable
(假设前1000条记录的状态都是0,然后第1001条记录的状态是1),那么它就不会foreach
通过线路传输大量数据(1001条记录)?@mjwills是的。对于IQueryable,将需要另一个解决方案(最好是一个可以在一个查询中返回结果且不获取任何行的解决方案)。如果GetHistory
从实体框架返回了IQueryable
,这是否可行?@mjwills否,因为IQueryable需要另一个解决方案。我没有想到。。。((它不会编译。假设GetHistory
返回1000个项目。第一个项目的状态为0。第二个项目的状态为1。此代码将迭代1000个项目中的多少项?@mjwillsAggregate
将迭代所有项目。如果GetHistory
返回内存集合,则这不是问题。对于IQueryable
@Vladimir Arustamian解决方案是最优的