2012-04-26 15 views
6

Ich benutze EntityFramework mit POCOs.
Angenommen, ich habe POCOs wie diese (vereinfacht) definiert:LINQ Abfrage mit einer WHERE-Klausel mit mehreren Bedingungen

class Class1 
{ 
    public int ID; 
    public int SomeNumber; 
} 

class Class2 
{ 
    public int ID; 
    public int SomeNumber; 
} 

class Class3 
{ 
    public int ID; 
    public int SomeNumber; 
} 

class SomeClass 
{ 
    public int ID; 
    public int? Class1ID; 
    public Class1 Class1; 
    public int? Class2ID; 
    public Class2 Class2; 
    public int? Class3ID; 
    public Class3 Class3; 
} 

ich alle SomeClass Datensätze aus der Datenbank abrufen möchten, die entweder eine von Class1, Class2 oder Class3 zu einem gehören, wo ClassX.SomeNumber einige Zahl entspricht.

Ich schrieb die LINQ-Abfrage, die wie folgt aussieht:

Database DB = new Database(); // object context 
var result = DB.SomeClass.ToList(); 

int SomeNumber = 1; // some number 
List<SomeClass> retValue = result 
    .Where(x => 
     { 
      int Number = 0; 
      if (x.Class1 != null) 
       Number = x.Class1.SomeNumber; 
      else if (x.Class2 != null) 
       Number = x.Class2.SomeNumber; 
      else if (x.Class3 != null) 
       Number = x.Class3.SomeNumber; 
      return Number == SomeNumber; 
     }) 
    .ToList(); 

... aber retValue keine Aufzeichnung enthält.

Die Lösung

Offenbar hatte ich .Include Aussagen angeben, da verzögertes Laden deaktiviert und x.Class1 war, x.Class2 und x.Class3 hatte immer den null Wert. Ich schäme mich dafür, dass ich nicht explizit gesagt habe, dass das Lazy Loading deaktiviert ist - das Problem wäre dann offensichtlich gewesen.

jedoch dank Ladislav der Post, verbesserte ich meinen Code in etwa so:

Database DB = new Database(); // object context 

int SomeNumber = 1; // some number 
List<SomeClass> retValue = DB.SomeClass 
    .Include("Class1") 
    .Include("Class2") 
    .Include("Class3") 
    .Where(x => 
     SomeNumber == x.Class1.SomeNumber || 
     SomeNumber == x.Class2.SomeNumber || 
     SomeNumber == x.Class3.SomeNumber) 
    .ToList(); 

ich nicht wusste, LINQ-to-Entities automatische Null Koaleszierstruktur durchführen soll.

Antwort

3

IMHO sollten Sie nur diese in Ordnung sein: alle Daten

Database DB = new Database(); 
var result = DB.SomeClass.Where(x => 
          Number == x.Class1.SomeNumber || 
          Number == x.Class2.SomeNumber || 
          Number == x.Class3.SomeNumber) 
         .ToList(); 

Ihre Anfrage Lasten und nach, dass Sie beurteilen Zustand in .NET = Sie müssen auf Null-Wert testen, bevor SomeNumber Zugriff, aber das ist nicht erforderlich, wenn Sie bewerten SomeNumber in SQL über Linq-to-Entities. Linq-to-Entities sollten automatisches Null-Coalescing durchführen.

+0

Eigentlich wurde die Lösung (ich es in der Regel selbst finden, kurz nachdem ich fragen), dass aufgrund verzögertes Laden deaktiviert , Musste ich tun 'var result = DB.SomeClass.Include (" Class1 "). Include (" Class2 "). Include (" Class3 ")' vor dem Ausführen der 'Where'-Klausel. Allerdings habe ich dies als akzeptiert markiert, weil Sie mir beigebracht haben, wie ich meinen Code verbessern kann (verwenden Sie 'Where' in LINQ-To-Entities direkt) –

2

Entsprechend Ihrer Logik, wenn x.Class1 nicht null ist, aber x.Class1.SomeNumber ist 3, wird es nicht alle anderen Klauseln überprüfen.

Wenn Sie überprüfen wollen, wenn nur einige ClassN.SomeNumber == SomeNumber, dann sollten Sie es wie folgt tun:

int SomeNumber = 1; // some number 
List<SomeClass> retValue = result 
    .Where(x => 
     { 
      if (x.Class1 != null && x.Class1.SomeNumber == SomeNumber) 
       return true; 
      else if (x.Class2 != null && x.Class2.SomeNumber == SomeNumber) 
       return true; 
      else if (x.Class3 != null && x.Class3.SomeNumber == SomeNumber) 
       return true; 
      return false; 
     }) 
    .ToList(); 
+0

Ist dieser Code nicht derselbe wie der, den ich benutzt habe, außer dass mein Code 1 mehr hat Linie? –

+0

Nein, da es sofort zurückkehrt, wenn die Nummern gleich sind. In Ihrem Code ist es möglich, dass es eine richtige Zahl gibt, die aber von einer anderen if-Klausel überschrieben wird. – LueTm

+0

Es kann nicht überschrieben werden, weil es "else" -Klauseln gibt, und würde 0 zurückgeben, wenn keine der Bedingungen zutrifft. –

Verwandte Themen