2017-05-03 4 views
3

ich eine LINQ-Abfrage verwenden Summe einer Spalte zu finden, und es gibt eine geringe Chance, dass der Wert in wenigen Fällen null sein könnteHandelte null in LINQ Summe Ausdruck

Die Abfrage ich jetzt benutze ist

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

wo domainstatement kann null und Score sein auch null sein kann

Jetzt, nach dieser Abfrage ausgeführt wird, erhalte ich die Fehler

Der Cast-to-Value-Typ 'Int32' ist fehlgeschlagen, da der materialisierte Wert null ist. Entweder der generische Parameter des Ergebnistyps oder die Abfrage müssen einen Nullwerttyp verwenden.

Also, wie kann ich null Ausnahmen wirksam behandeln und Summe als INT-Wert zurückgeben?

+0

int score = dbContext.domainmaps.Where (p => p.SchoolId == schoolid) .sum (v => (v? .domainstatement? .Score) .GetValueOrDefault()); Funktioniert das? Da der Standardwert für eine ganze Zahl 0 ist, sollte die Summierung dieser Funktion ohne Probleme funktionieren, aber ich weiß nicht, ob ich die Syntax korrekt habe. – thinklarge

+0

Gibt es eine Domain-ID? –

+0

Verwenden Sie wirklich LINQ-2-SQL statt EF? –

Antwort

3

Verwenden DefaultIfEmpty Erweiterungsmethode:

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

Ihr Problem ist, gibt es keine Organisationen, die mit diesem schoolId wie diese .Something wird der SQL-Code wird erzeugt werde:

-- 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

Dies wird nicht eine Null-Referenz Ausnahme auslösen, wenn v.domainstatement == null? Das ist großartig, danke für den Zeiger! – thinklarge

+1

Dies wird eine Nullref-Ausnahme verursachen. Stattdessen sollten Sie den Filter zum Entfernen von Domänenzuordnungen hinzufügen, wobei v.domainstatement ebenfalls null ist. '.Where (p => p.SchoolId == schoolid && p.domainstatement! = Null) .DefaultIfEmpty (0) .Sum (v => v.Score ??0): –

+0

Sie haben Recht @TravisJ, wenn die Beziehung optional ist, dann könnte es null sein, danke – octavioccl

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

Die Standardwert von einem int? ist 0. Also sollte das funktionieren.

+0

Ich denke nicht, dass der Operator mit Nullbedingungen von Abfrageanbietern unterstützt wird. –

+0

@TravisJ das ist interessant. Ich hatte wirklich gehofft, dass die Op mit Ja oder Nein antworten würde, ob das funktionierte oder nicht. Ich habe kein dbContext-Beispiel, an dem ich das ausprobieren könnte, sonst würde ich es tun. – thinklarge

2

einiger Zeit Ihr domainstatement Kontext null so zu Linq-Abfrage verwendet

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

Hier

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

Sie haben einfach den Null-Koaleszenz-Operator an der falschen Stelle. Normalerweise wird ein solcher Fehler dadurch gelöst, dass der nicht nullable-Typ auf Nullwert heraufgestuft wird (keine DefaultOrEmpty und Null-Checks erforderlich sind), aber hier haben Sie bereits einen Nullable-Typ, und mit null-coalescing-Operator haben Sie das Gegenteil von dem gemacht, was die Fehlermeldung Ihnen sagt - Die Abfrage muss einen nullfähigen Typ verwenden.

einfach es nach bewegen die Sum Anruf und das Problem ist weg:

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