在LINQ求和表达式中处理null

Jib*_*hew 5 c# linq entity-framework

我正在使用LINQ查询来查找列的总和,并且在极少数情况下该值可能很小

我现在使用的查询是

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

where domainstatement可以为null,score也可以为null

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

转换为值类型"Int32"失败,因为实现值为null.结果类型的泛型参数或查询必须使用可空类型.

那么如何有效地处理null异常并将sum作为INT值返回呢?

oct*_*ccl 5

使用DefaultIfEmpty扩展方法:

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

你的问题是没有实体。schoolId像这样的 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]
Run Code Online (Sandbox Code Playgroud)


Iva*_*oev 5

这里

Sum(v => v.domainstatement.Score ?? 0);
Run Code Online (Sandbox Code Playgroud)

您只是将null-coalescing运算符放在了错误的位置。通常,通过将非可空类型提升为可空类型来解决此类错误(不需要DefaultOrEmpty进行空检查),但是在这里,您已经具有可空类型,并且使用空合并运算符执行的操作与错误消息告诉您的相反:查询必须使用可为null的类型

只需在通话后将其移动,Sum问题就消失了:

Sum(v => v.domainstatement.Score) ?? 0;
Run Code Online (Sandbox Code Playgroud)