如果求和值都为null,如何使linq和返回null

如果求和值都为null,如何使linq和返回null,linq,sum,nullable,Linq,Sum,Nullable,我有一个LINQ查询,看起来像这样 var duration = Level3Data.AsQueryable().Sum(d => d.DurationMonths); 如果所有d.DurationMonths值均为空,则总和返回0。如果所有的d.DurationMonths都是null,如何使总和返回null?或者我需要先运行一个单独的查询来消除这种情况,然后再执行求和吗?以及前面关于扩展方法的建议-您可以使用三元运算符 var duration = Level3Data.AsQue

我有一个LINQ查询,看起来像这样

var duration = Level3Data.AsQueryable().Sum(d => d.DurationMonths);

如果所有
d.DurationMonths
值均为空,则总和返回
0
。如果所有的
d.DurationMonths
都是
null
,如何使总和返回
null
?或者我需要先运行一个单独的查询来消除这种情况,然后再执行求和吗?

以及前面关于扩展方法的建议-您可以使用三元运算符

var duration = Level3Data.AsQueryable().Any(d => d.DurationMonths.HasValue) 
               ? Level3Data.AsQueryable().Sum(d => d.DurationMonths) 
               : null;

仅使用总和,这是不可能的。正如您在问题中指出的,在调用Sum之前,您需要检查此情况:

var q = Level3Data.AsQueryable();
var duration = q.All(d => d.DurationMonths == null)
                   ? null
                   : q.Sum(d => d.DurationMonths);

您可以使用
Aggregate
提供自定义聚合代码:

var items = Level3Data.AsQueryable();
var duration = items.Aggregate<D,int?>(null, (s, d) => (s == null) ? d.DurationMonths : s + (d.DurationMonths ?? 0));
var items=Level3Data.AsQueryable();
var持续时间=项目.聚合(空,(s,d)=>(s==null)?d.DurationMonths:s+(d.DurationMonths±0));

(假设
Level3Data
中的项目类型为
D

如果您希望结果不需要两次查询,请尝试:

var duration=Level3Data.AsQueryable().Sum(d=>(double?)d.DurationMonths)

如果希望此查询结果为零而不是null,请使用:

var duration=Level3Data.AsQueryable().Sum(d=>(双倍?)d.DurationMonths)??0;

您可以显式地将不可为null的varaible类型转换为可为null的类型。
即,选择(int?)outputindIndicatorTable.Status).Sum()

持续时间月的类型是什么?智力
Nullable
?虽然这会枚举两次结果,但我的集合很小,我觉得这是最可读的。所以我接受了。谢谢大家。呸,晚了不到一分钟。LolI个人最喜欢这个选项。如果并且所有值都是
null
,那么对于
Sum
,Linq2Sql将返回
null
,而Linq2Object将返回
0
。OP返回了
0
,因此他们使用的是LINQ2对象,在这种情况下,求和之前将其转换为
double?
,结果仍然是
0
。这个答案是错误的。求和前强制转换到
(int?
)在Linq2Sql上下文中是有意义的,其中
Sum
可以返回
null
(直接来自SQL查询),即使编译器推断出不可为null的结果,这会导致异常。对于LINQ2对象,
Sum
始终返回
0
,即使所有输入元素都是
null
或根本没有输入元素。
+=
实际上应该是
+
var outputIndicatorSum = (from OutputIndicatorTable in objDataBaseContext.Output_Indicators
                                          where OutputIndicatorTable.Output_Id == outputId
                                          select (int?)OutputIndicatorTable.Status).Sum();
                int outputIndicatorSumReturn = Convert.ToInt32(outputIndicatorSum);
                return outputIndicatorSumReturn;