2012-04-26 16 views
6

Używam EntityFramework z POCO.
Załóżmy, że mam Poços zdefiniowane następująco (uproszczony):Zapytanie LINQ z klauzulą ​​WHERE z wieloma warunkami

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

Chcę pobrać wszystkie SomeClass rekordy z bazy danych, które należą do jednej z Class1, Class2 lub Class3 gdzie ClassX.SomeNumber równa jakiś numer.

napisałem kwerendy LINQ, która wygląda tak:

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(); 

... retValue jednak nie zawiera żadnego rekordu.

Rozwiązanie

Widocznie musiałem podać .Include sprawozdań bo leniwy ładowanie było wyłączone i x.Class1, x.Class2 i x.Class3 zawsze miał wartość null. Wstydzę się, ponieważ nie powiedziałem jednoznacznie, że leniwy ładunek został wyłączony - problem byłby wówczas oczywisty.

Jednak dzięki postu Ladislav za, ja poprawiłem swój kod tak:

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(); 

Nie wiedziałem LINQ-Podmioty powinny wykonywać automatyczne zerowej koalescencyjne.

Odpowiedz

3

IMHO powinno być OK z tylko to:

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

wczytaniu zapytania wszystkie dane, a potem ocenić stan w .NET = należy sprawdzić wartość null przed dostępem SomeNumber ale to nie jest potrzebne, jeśli oceniasz SomeNumber w SQL przez Linq-to-entity. Linq-to-entity powinno wykonać automatyczną koalescencję zerową.

+0

Właściwie roztwór (I zazwyczaj znaleźć się wkrótce po pytam), które ze względu na leniwe załadunku wyłączony , Musiałem zrobić 'var result = DB.SomeClass.Include (" Class1 ") .Zawrzyj (" Class2 ") .Zawrzyj (" Class3 ")' przed uruchomieniem klauzuli "Where". Jednak zaznaczam to jako zaakceptowane, ponieważ nauczyłeś mnie, jak ulepszyć mój kod (użyj 'Where' w LINQ-to-Entities bezpośrednio) –

2

Zgodnie z logiką, jeśli x.Class1 nie ma wartości null, ale x.Class1.SomeNumber ma wartość 3, nie sprawdzi wszystkich pozostałych klauzul.

Jeśli chcesz sprawdzić, czy tylko niektóre ClassN.SomeNumber == SomeNumber, to należy to zrobić tak:

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

Czy ten kod nie jest taki sam jak ten, którego użyłem, z tym, że mój kod ma jeszcze 1 linia? –

+0

Nie, ponieważ zwraca natychmiast, jeśli liczby są równe. W twoim kodzie jest możliwe, że istnieje prawidłowa liczba, ale zostaje ona zastąpiona inną klauzulą ​​if. – LueTm

+0

Nie można go przesłonić, ponieważ istnieją klauzule "else" i zwrócą wartość 0, jeśli żaden z warunków nie będzie zgodny. –

Powiązane problemy