2017-05-03 74 views
3

我使用LINQ查询发现一列的总和,并有轻微的机会,该值可能在少数情况下处理空

为空

我现在使用的查询是

int score = dbContext.domainmaps.Where(p => p.SchoolId == schoolid).Sum(v => v.domainstatement.Score ?? 0); 

其中domainstatement可以为空,也得分可以为空

现在执行这个查询后,我收到错误

由于物化值为空,所以强制转换为值Int32类型失败。结果类型的泛型参数或查询都必须使用可为空的类型。

那么我怎样才能有效地处理空例外,并返回作为INT值的总和?

+0

INT得分= dbContext.domainmaps.Where(P => p.SchoolId == schoolid).SUM(V => (ⅴ.domainstatement .Score?).GetValueOrDefault()); 这是否工作?因为整数的默认值是0,所以这个总和应该没有问题,但我不知道我的语法是否正确。 – thinklarge

+0

是否有'domainstatement' id? –

+0

你真的使用LINQ-2-SQL而不是EF吗? –

回答

3

使用DefaultIfEmpty扩展方法:

int score = dbContext.domainmaps.Where(p => p.SchoolId == schoolid 
             && p.domainstatement != null) 
           .DefaultIfEmpty() 
           .Sum(v => v.domainstatement.Score ?? 0); 

你的问题是有没有与schoolId实体.Something这样是SQL代码将产生:

-- Region Parameters 
DECLARE @p0 Int = 3 
DECLARE @p1 Int = 0 
-- EndRegion 
SELECT SUM([t3].[value]) AS [value] 
FROM (
    SELECT COALESCE([t2].[Score ],@p1) AS [value] 
    FROM (
     SELECT NULL AS [EMPTY] 
     ) AS [t0] 
    LEFT OUTER JOIN (
     SELECT [t1].[Score ] 
     FROM [domainmaps] AS [t1] 
     WHERE [t1].[SchoolId] = @p0 
     ) AS [t2] ON 1=1 
    ) AS [t3] 
+0

如果v.domainstatement == null,这不会引发空引用异常吗?这是真棒感谢指针! – thinklarge

+1

这将导致null ref异常。相反,您应添加删除v.domainstatement也为空的域映射的过滤器。 '.Where(p => p.SchoolId == schoolid && p.domainstatement!= null).DefaultIfEmpty(0).Sum(v => v.Score ??0);' –

+0

你是对的@TravisJ,如果关系是可选的,那么它可能为空,谢谢 – octavioccl

1
int score = dbContext.domainmaps.Where(p => p.SchoolId == schoolid).Sum(v => (v?.domainstatement?.Score).GetValueOrDefault()); 

的任何int的默认值?是0.所以这应该工作。

+0

我不认为查询提供程序支持空条件运算符。 –

+0

@TravisJ很有趣。我真的希望这个机构会回答是或否,以确定它是否有效。我没有dbContext的例子,我可以试试这个,否则我会。 – thinklarge

2

一段时间此致domainstatement语境空,因此使用LINQ查询

 
int score = dbContext.domainmaps.Where(p => p.SchoolId == schoolid && p.domainstatement!=null && p.domainstatement.Score!=null).ToList().Sum(v => v.domainstatement.Score); 
2

这里

Sum(v => v.domainstatement.Score ?? 0); 

你刚刚把空合并运算上错了地方。通常这样的错误是通过将非空类型提升为空(无需DefaultOrEmpty并且需要空检查)来解决的,但在这里您已经有了一个可为空的类型,并且使用空合并运算符,您做出了与错误消息告诉您相反的结果 - 查询必须使用可空类型

只需将它Sum电话后问题消失了:

Sum(v => v.domainstatement.Score) ?? 0;