Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# LINQ查询检查一个集合是否包含两个具有特定值的记录?_C#_Linq - Fatal编程技术网

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个项目中的多少项?@mjwills
Aggregate
将迭代所有项目。如果
GetHistory
返回内存集合,则这不是问题。对于
IQueryable
@Vladimir Arustamian解决方案是最优的