C# Linq查询分组,检查结果是否为空

4
如果我有这样的一个类
public class Test
{
   public string Id {get; set;}
   public string Name {get; set;}
   public int Value {get; set;}
}

然后:

List<Test> values = new List<Test>(); // this contains let's say 10 items

我喜欢这样做:

var grouped = values.Where(x=>x.Value > 10).GroupBy(x=>x.Name);

我的问题是如何检查grouped == null,或者如何检查没有符合该条件的分组?我问这个问题是因为如果我像这样做:
if (grouped == null) // this is false although the linq yielded no results
{

}

在 GroupBy 或其他函数之后调用 .ToList() 以使 Linq 查询得到评估。然后您可以检查列表是否为空。 - Ron Beyer
5个回答

6
您可以使用方法Any()
var anyItems = grouped.Any();

您不需要检查是否为空,因为分组操作会返回一个空集合而不是null。


5
您可以检查是否没有组,如下所示:

您可以检查是否没有组,如下所示:

var anyGroups = grouped.Any();

如果至少有一个组,则被称为Any的扩展方法将返回true。否则它将返回false
根据MSDN,这是GroupBy方法的签名:
public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>(
    this IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector)

从上面可以清楚地看出,这种方法返回实现了IGrouping接口的项目序列。(IGrouping表示具有相同键的对象集合)。检查序列是否包含元素的简单方法是使用可枚举的扩展方法Any
此外,在不传递任何谓词的情况下使用Any方法是一个O(1)操作。而在某些情况下,使用可枚举的扩展方法Count是一个O(n)操作。

那很容易!谢谢! :) - user2818430
@user2818430 不客气,伙计。我很高兴能够帮助到你。 - Christos

2

GroupBy 永远不会返回 null。当结果中没有记录时,您将获得一个空的 IEnumerable<IGrouping<TKey, TSource>> 对象。

在您的情况下,GroupBy 是不必要的:您可以使用以下内容替换它:

var anyGreaterThanTen = values.Any(x=>x.Value > 10);

0

使用Any()已经足够好了,但它并不是最优解。

显然,在找到一些结果后,您需要遍历结果,但在遍历结果之前调用Any()会导致查询运行两次。对于像这里的简单示例来说,这并不是什么大问题,但如果是针对数据库的查询(LINQ to SQL或Entity Framework),那么就会有两个数据库访问。一次是检查是否有任何结果,下一次是获取结果。

为了避免这种情况,您可以编写:

bool hasResult = false;
// iterating over the result, and performing your task
foreach(var group in grouped)
{
    hasResult = true;

    // process data
    // ...
}

if(!hasResult)
{
    // ...
}

0

在检查结果是否为空时,我遇到了同样的问题。因此,我进行了调试。 我发现当结果没有组时,有时它没有元素或只有1个元素,但是这个元素为空。因此,为了检查结果不为空,我们应该像下面这样结合2个条件:

if(grouped.Count() > 0 && grouped.ElementAt(0) != null)
    {
       //TODO:....enter code here
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接