【问题标题】:How to handle "InvalidOperationException Sequence contains no elements"如何处理“InvalidOperationException 序列不包含任何元素”
【发布时间】:2022-01-03 10:03:56
【问题描述】:

我有一个返回一个月平均销售额的简单函数。但是,当新的一个月开始时,没有记录,我得到了以下异常:

System.InvalidOperationException: '序列不包含任何元素。'

public double GetTotalMonthlyAvgSales()
{
    return _DbContext.Carts.Where(x => x.Created.Month == DateTime.UtcNow.Month && x.Created.Year == DateTime.UtcNow.Year).Select(x => x.TotalAmount).Average();

}

处理此异常的最佳方法是什么?

【问题讨论】:

  • 好吧,只有在_DbContext.Carts.Where(x => x.Created.Month == DateTime.UtcNow.Month && x.Created.Year == DateTime.UtcNow.Year).Select(x => x.TotalAmount)中有元素时才调用Average()?拆分通话并使用Any()检查内容是一种解决方案。
  • 最好先使用Any() 检查是否有匹配的购物车商品。如果没有,则可能返回0-1,但该值由您决定。 null 可能是更有意义的响应,如果您可以将返回类型更改为 double?
  • 如果where方法没有返回记录,你想返回什么?

标签: c# asp.net .net asp.net-mvc


【解决方案1】:

如果抛出异常,最简单的方法可能是用 try ... catch 包围块并返回 0(或您想要的任何其他默认值)

public double GetTotalMonthlyAvgSales()
{
  try {
    return _DbContext.Carts.Where(x => x.Created.Month == DateTime.UtcNow.Month && x.Created.Year == DateTime.UtcNow.Year).Select(x => x.TotalAmount).Average();
  } catch (InvalidOperationException ex) {
    //if it's an InvalidOperationException return 0
    return 0;
  }
  //any other exception will be rethrown
}

但由于异常很昂贵,您可以检查您尝试计算平均值的集合是否包含任何元素

public double GetTotalMonthlyAvgSales()
{
  var col = _DbContext.Carts.Where(x => x.Created.Month == DateTime.UtcNow.Month && x.Created.Year == DateTime.UtcNow.Year);
  if (col.Any()) {
    //if the collection has elements, you can calculate the average
    return col.Select(x => x.TotalAmount).Average();
  }
  //if not, return 0
  return 0;
}

【讨论】:

  • 我想像你的第二次尝试那样做,但我更喜欢第一次。谢谢!
  • 其实我更喜欢第二个。因为“异常”应该是(顾名思义)异常的东西,不应该用于定义控制流。在您的用例中,拥有一个空集合似乎并不是什么“异常”,因此您应该尝试防止异常。此外,异常处理非常昂贵。
猜你喜欢
  • 2015-02-19
  • 1970-01-01
  • 1970-01-01
  • 2014-06-25
  • 1970-01-01
  • 2022-09-30
  • 2015-09-04
  • 2013-02-07
  • 2015-11-23
相关资源
最近更新 更多