使用linq处理聚合中的空字段

时间:2015-11-24 12:06:16

标签: c# linq

我遇到过我在LINQ查询中总结的情况。

该属性实际上可能在数据库中有NULL

但是,当我们使用LINQ i.e. SUM

在集合中的同一字段上应用聚合it calculates/returns 0 for null

我正在避免sum for null字段。

TotalDays = x.Select(y => y.day.HasValue ? x.Sum(z => z.day) : null).FirstOrDefault(),

是好的方式还是可以更好?

1 个答案:

答案 0 :(得分:2)

Null值总和为零,因为它们既不能添加也不能减去计数,所以在这种情况下通常会想要为零。

考虑:

(new int?[]{0, null, 3, 2}).Sum() // result is 5. Other linq providers do similar.

如果您想分别记录全零结果集,那么这有时会导致问题:

(new int?[]{null, null}).Sum() // result is 0, but maybe we want to note that there was indeed no values.

我们可以这样做:

source.Any(x => x.HasValue) ? source.Sum() : default(int?);

回到你的例子中的是:

int? totalDays = x.Any(y => y.day.HasValue) ? x.Sum(y => y.day) : default(int?);

但您可能更喜欢这样做:

int? totalDays = x.Sum(y => y.day);
if (totalDays == 0 && y.All(y => !y.day.HasValue))
  totalDays = null;

然后你只检查集合,看看在收到0结果的情况下所有值是否为空(在这种情况下,任何其他结果都不可能)。

当all-null结果更常见时,首先检查Any()会更有效率,而当all-null结果不太常见时,首先执行Sum()会更有效,因为在每种情况下你只做两次在不太常见的情况下进行操作。