如何在空集合中使用聚合运算符来避免Linq异常?

时间:2012-05-18 08:56:33

标签: linq c#-4.0

我喜欢在db表上编写合成查询,如下所示:

Decimal sum = MyDataContext.MyTable.Where(el => el.Client == selectedClien).Sum(el => el.Value.GetValueOrDefault(0));

不幸的是,如果where子句根本不返回任何元素,则会抛出错误。 在使用.Sum之前我应该​​检查.Any如果我有一些元素,但结果代码与初始代码相比是丑陋的。不要认为放一个try / catch块是一个很好的解决方案。

您是否有更好的建议以下代码?

if (MyDataContext.MyTable.Where(el => el.Client == selectedClien).Any())
  sum =  MyDataContext.MyTable.Where(el => el.Client == selectedClien).Sum(el => el.Value.GetValueOrDefault(0));
else sum = 0;

由于 菲利普

经过多次调查后添加:

MyDataContext.MyTable.Where(el => el.Client == selectedClien).Sum(el => el.Value).GetValueOrDefault(0)

当集合为空时,上面的代码很有效。我把'GetValueOrDefault(0)'放在lambda里面.Sum()里面的原因是'Value'字段是Decimal ?,所以它可以为null。我还没有测试过一些元素有空值的情况。

2 个答案:

答案 0 :(得分:1)

为了避免这种情况,我写了一个扩展名。

    public static decimal? SafeSum<T>(this IEnumerable<T> source, Func<T, decimal?> selector)
    {
        try
        {
            return source.Sum(selector);
        }
        catch
        {
            /* ignore exception */
            return null;
        }
    }

答案 1 :(得分:0)

令人惊讶(对我而言)我介绍了一个可能的异常原因,试图让我的代码更健壮! 编写健壮代码的正确方法如下:

Decimal sum = MyDataContext.MyTable.Where(el => el.Client == selectedClien).Sum(el => el.Value).GetValueOrDefault(0);

如上面的评论和msdn文档中所述

Enumerable.Sum<TSource> Method (IEnumerable<TSource>, Func<TSource, Nullable<Decimal>>)

对空值和空集合很有效。 GetValueOrDefault()确保它返回一个非空的十进制。

无论如何,为什么初始代码抛出异常仍然不太清楚。