【问题标题】:LINQ Max extension method gives an error on empty collectionsLINQ Max 扩展方法在空集合上出错
【发布时间】:2012-09-13 20:56:27
【问题描述】:

我有以下疑问:

var maxNumber = dbContext.Where(a => a.Id == 9).Max(a => a.Sample_Num);

如果没有 9 的 Id,我得到一个错误。如果没有 9 的 Id,我喜欢将结果默认为 0。

我试过了:

var maxNumber = dbContext.Where(a => a.Id == 9).Max(a => a.Sample_Num) ?? 0; 

以及其他变体,但无法使其工作

【问题讨论】:

  • 我在上面的代码中看不到任何 GroupBy... :)

标签: c# linq


【解决方案1】:

您可以使用Any 来检查是否有匹配的元素:

int maxNumber = 0;
var id9 = dbContext.Where(a => a.Id == 9);
if(id9.Any())
{
    maxNumber = id9.Max(a => a.Sample_Num);
}

或者你可以使用DefaultIfEmpty(defaultValue):

int maxNumber = dbContext
    .Where(a => a.Id == 9)
    .Select(a => a.Sample_Num)
    .DefaultIfEmpty(0)
    .Max();

【讨论】:

  • 同意。我讨厌使用Any(),因为它会强制枚举第二次。
  • Select + DefaultIfEmpty + Max 是您想要 MaxOrDefault 时的最佳选择。
  • 请注意,对于IQueryable<T> 和某些提供程序(cough NHibernate),DefaultIfEmpty 未实现。我写了自己的 MaxOrDefault:query.OrderByDescending(expression).Select(expression).FirstOrDefault();
  • 排序找到最大值不是很有效。较小的数据集可能不会太明显,但数据集越大,您花费的时间就越多,将您不关心的所有其他值按顺序排列。
  • @KenLyon 您的评论是指上一条评论还是我的回答?
【解决方案2】:

只需使用 Max 的可为空版本(即使聚合的值不可为空): var maxNumber = dbContext.Where(a => a.Id == 9).Max(a => (int?)a.Sample_Num) ?? 0;

这几乎是 Nate 尝试过的。 关键是 Max of nullables 给出了空集合中的 null 作为结果,而 Max of ints 给出了一个异常,因为它的返回值是集合的现有 int。 您通过显式声明该类型的结果来强制它为 Max。 然后你可以在??之后指定所需的默认值。

【讨论】:

    【解决方案3】:

    您可以尝试 MaxOrDefault 的简单实现,而无需进行任何转换。只需检查 Max 函数中的选择器参数即可:

    var maxNumber = dbContext.Where(a => a.Id == 9).Max(a => a?.Sample_Num) ?? 0;
    

    【讨论】:

      猜你喜欢
      • 2013-12-31
      • 1970-01-01
      • 2011-04-04
      • 2011-11-08
      • 1970-01-01
      • 1970-01-01
      • 2012-03-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多