2013-01-16 5 views
6

Ich versuche, die folgende LINQ-Abfrage mit Entity Framework 5 auszuführen:LINQ to Entities Join auf Nullable-Feld, wo Null Impliziert "Match All"

int taskId = 2; 

query = from a in Table_A 
     where a.StatusCode != "DONE" 
      && a.Inbound 
     join b in Table_B 
      on a.Id equals b.Id_Table_A 
     join c in Table_C 
      on a.State equals (c.State ?? a.State) 
     where 2 == c.Id_Task 
      && b.DataType == c.DataType 
     select a.Id; 

Die Linie, die mir Probleme verursacht ist:

on a.State equals (c.State ?? a.State) 

Das "State" -Feld in Tabelle_C ist Nullable ... und wenn es Null ist, wird es verwendet, um "alle Zustände" zu implizieren. Wenn also "c.State" gleich null ist, möchte ich, dass der Datensatz übereinstimmt. Wenn ich dies in SQL zu schreiben, würde ich folgendes:

JOIN Table_C ON Table_A.State = ISNULL(Table_C.State, Table_A.State) 

Leider bin ich wird die folgende Fehlermeldung gegeben:

Der Name ‚a‘ ist in ihrem Umfang nicht auf der rechten Seite von 'gleich'. Erwägen Sie, die Ausdrücke auf beiden Seiten von 'gleich' zu vertauschen.

Ich werde jedem dankbar sein, der mich über das Geheimnis informieren kann, dass es funktioniert.

Danke.

+0

Statt 'on a.State equals (c.State ?? a.State)' versuchen Sie dies: 'on (c.State == null || a.State gleich c.State)' – Anchit

+0

Danke Anchit ... aber das geht leider nicht. Ich erhalte den folgenden Fehler: Der Name 'c' ist nicht im Bereich auf der linken Seite von 'gleich'. Erwägen Sie, die Ausdrücke auf beiden Seiten von 'gleich' zu vertauschen.

+0

überprüfen Sie meine Antwort, es sollte funktionieren. Lass es mich wissen, wenn es nicht so ist. – Anchit

Antwort

1

Ich habe es geschafft, dies zu arbeiten, indem Sie die "DataType" -Kontrolle von der WHERE zum JOIN bewegen und die "State" -Kontrolle vom JOIN zum WHERE verschieben. Der resultierende Code, der wie erwartet funktionierte, lautet wie folgt:

query = from a in Table_A 
     where a.StatusCode != "DONE" 
      && a.Inbound 
     join b in Table_B 
      on a.Id equals b.Id_Table_A 
     join c in Table_C 
      on b.DataType equals c.DataType 
     where 2 == c.Id_Task 
      && (c.State ?? a.State) == a.State 
     select a.Id; 

Vielen Dank an alle, die sich das für mich angesehen haben. :)

1

Sie können den Code ändern wie:

int taskId = 2; 

query = from a in Table_A 
     where a.StatusCode != "DONE" 
      && a.Inbound 
     join b in Table_B 
      on a.Id equals b.Id_Table_A 
     from c in Table_C 
     where 2 == c.Id_Task 
      && b.DataType == c.DataType 
      && (c.State == null || a.State.Equals(c.State)) 
     select a.Id; 

A join im Wesentlichen eine where Klausel ist, so können wir hier die where Klausel aufgrund der Beschränkungen mit join verwenden.

+0

Danke nochmal Anchit. Das funktioniert in meinem Fall auch nicht, weil im Modell keine Beziehung zwischen "Table_C" und "Table_A" besteht. Das Ausführen der Abfrage führte zum Auslösen einer NotSupportedException mit der Beschreibung "Es konnte kein konstanter Wert vom Typ '[type for Table_C] erstellt werden. In diesem Kontext werden nur primitive Typen oder Aufzählungstypen unterstützt." –

+0

Damit dieser Code funktioniert, muss keine Beziehung zwischen Table_C und Table_A bestehen. Ich habe meinen ersten Post bearbeitet, also hast du vielleicht etwas verpasst. Kannst du den tatsächlich verwendeten Code posten? Das Problem, das ich denke, ist, dass Sie in der 'where' Bedingung' c == null' anstelle von 'c.State == null' gesetzt haben. – Anchit

+0

Ich habe überprüft, dass ich == und nicht = ... verwendet habe, und ich habe es genauso gemacht wie gesagt. Es wirft immer noch diese Ausnahme. Ich denke, ich habe vielleicht eine Lösung gefunden; indem Sie etwas finden, dem Sie sich anschließen und den Filter "State" in der WHERE-Klausel verwenden können; ähnlich wie du es gemacht hast. Sobald ich es getestet habe, werde ich es veröffentlichen. :) –