2016-04-04 5 views
0

Ich habe LINQ Abfrage, die äußere zwei Tabellen verlassen. Ich fand, wenn ein Wert eines Feldes Null zurückgibt, dann werde ich eine Fehlermeldung erhalten:Null-Wert im Ergebnis eines linken äußeren Joins Linq verursacht Fehler

"Die Umwandlung in Werttyp 'System.Int32' ist fehlgeschlagen, weil der materialisierte Wert Null ist. Entweder der generische Parameter des Ergebnistyps oder Die Abfrage muss einen Nullwerttyp verwenden. "

kopiert ich meine Linq unter:

var SrvRef = from s in db.SrvHeads 
    join r in db.Referrants on s.svhReferrer equals r.refID into r_join 
    from r in r_join.DefaultIfEmpty() 
    where s.svhAccID == accId && 
    s.svhHeadCnt == HeadId 
    select new 
    { 
    s.svhBalance, 
    r.refID 
    }; 
bool FBeenPaid = SrvRef.FirstOrDefault().svhBalance == 0M; //this causes error 

Wie kann ich dieses Problem beheben?

Antwort

7

Ich bin du bist immer auf die Art der Fehler ein wenig überrascht, aber es gibt zwei Orte, die Sie wegen der Möglichkeit des Ergebnisses ist null nehmen müssen:

  • Innerhalb der Abfrage, wo r kann null sein. (Wenn Sie wollen nicht übereinstimmen, wenn es keine Elemente in r_join sind passende s, sollten Sie keine Links außen verwenden Join)
  • Im Ergebnis selbst: Sie FirstOrDefault() verwenden, welche null zurück, wenn SrvRef ist leer.

So auf den ersten Blick sollte es wohl so etwas wie:

bool beenPaid = query.FirstOrDefault()?.svhBalance == 0m ?? false; 

Having said that:

var query = from s in db.SrvHeads 
    join r in db.Referrants on s.svhReferrer equals r.refID into r_join 
    from r in r_join.DefaultIfEmpty() 
    where s.svhAccID == accId && s.svhHeadCnt == HeadId 
    select new 
    { 
     s.svhBalance, 
     refId = r == null ? 0 : r.refID // Adjust to the appropriate type of refID 
    }; 
var result = query.FirstOrDefault(); 
bool beenPaid = result != null && result.svhBalance == 0m; 

Mit C# 6 können Sie die unteren zwei Zeilen ändern

  • Sie verwenden derzeit refId im Ergebnis sowieso nicht - Warum nimmst du es in das Ergebnis?
  • Sind Sie sicher, dass Sie überhaupt eine linke äußere Verbindung wollen?
  • Sind Sie sicher, dass die erste Ergebnis wirklich ist, was Sie wollen? Was passiert, wenn mehrere Ergebnisse im Join enthalten sind?
  • Gibt es einen Grund, warum Sie das Ganze nicht in einer Abfrage tun? Etwas wie:

    var paid = db.SrvHeads 
          .Where(s => s.svhAccID == accId && s.svhHeadCnt == HeadId) 
          .Any(s => db.Refererrants.Any(r => s.svhReferrer == r.refID 
            && s.svhBalance == 0m); 
    

    .. aber nur für die präzise Semantik, die Sie wollen.

+0

Hallo, Vielen Dank für die Hilfe . Ich brauche wirklich die linke äußere Verbindung. und ich brauche das RefId und benutze es später. Ich brauche nur die erste Reihe, und eigentlich sollte es nur eine Reihe geben. Wenn ich die Maus über den SrvRef halte, habe ich die SQL-Anweisung, ich führe die SQL in der SQL-Management-Studio, es gibt ein Ergebnis mit RefId = null. so hat der sql keine probleme. Wenn ich die refId von linq entferne, gibt es auch kein Problem. Das Problem wird daher durch ein Nullwertfeld in der SELECT-Klausel verursacht. – peter

+0

@peter: Es ist nicht 'r.refId', das ist null hier, es ist' r' - weshalb das Extrahieren von 'r.refId' fehlschlägt. Das ist, was mein Code berücksichtigt. –

1

was ich denke, ein Fehler verursacht ist, dass svhBalance ein int32 Werttyp ist und Sie einen Nullwert zurück von SrvRef.FirstOrDefault Zugriff(). Bitte versuchen Sie die folgende Zeile und lassen Sie mich wissen, wenn es Ihnen geholfen hat.

wenn svhBalance int-Wert-Typ ist

var SrvRefObj = SrvRef.FirstOrDefault(); bool FBeeenPaid = (((SrvRefObj! = null) & & (SrvRefObj.svhBalance ! = null))? (SrvRefObj.svhBalance == 0) :(falsch))

sonst, wenn es ein Dezimalwert Typ

var SrvRefObj = SrvRef.FirstOrDefault(); bool FBeenPaid = (((SrvRefObj! = null) & & (SrvRefObj.svhBalance ! = null))? (SrvRefObj.svhBalance == 0 M) :(falsch))

+0

Vielen Dank für Ihre Hilfe. Das Problem tritt auf, wenn die linq das Ergebnis zurückgibt. – peter

+0

Danke Peter für die Antwort. Wenn Sie denken, dass es Ihr Problem gelöst hat, dann markieren Sie es als Beantwortet. Grüße –

Verwandte Themen