2012-04-26 2 views
6

Я использую EntityFramework с POCOs.
Предположим, у меня есть POCO которые определены как это (упрощенный):Запрос LINQ с предложением WHERE с несколькими условиями

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

Я хочу, чтобы извлечь все SomeClass записи из базы данных, которые принадлежат к любой из Class1, Class2 или Class3 где ClassX.SomeNumber равно некоторое число.

Я написал запрос LINQ, который выглядит следующим образом:

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 не содержит никаких записей.

Раствор

Видимо, я должен был указать .Include заявления, потому что ленивая загрузка была отключена и x.Class1, x.Class2 и x.Class3 всегда имел значение null. Мне стыдно, потому что я явно не заявлял, что ленивая загрузка отключена - тогда проблема была бы очевидна.

Однако благодаря сообщению Ладислава, я улучшил свой код следующим образом:

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

Я не знаю, LINQ к Entities должно выполнять автоматические нулевые коалесцирующий.

ответ

3

ИМХО вы должны быть в порядке только с этим:

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

ваших нагрузок запросов все данные и после этого оценить состояние в .NET = вы должны проверить нулевое значение перед доступом SomeNumber, но это не требуется, если вы оцениваете SomeNumber в SQL через Linq-to-entity. Linq-to-entity должны выполнять автоматическое объединение нулей.

+0

На самом деле решение было (я обычно сам вскоре после того, как я прошу), что из-за отложенной загрузки отключены , Я должен был выполнить «var result = DB.SomeClass.Include (« Class1 »). Включить (« Class2 »). Включить (« Class3 ») перед выполнением предложения« Where ». Однако я отмечаю это как принятое, потому что вы научили меня улучшать мой код (напрямую используйте «Где» в LINQ-To-Entities) –

2

Согласно вашей логике, если x.Class1 не является нулевым, но x.Class1.SomeNumber равно 3, он не будет проверять все остальные предложения.

Если вы хотите проверить, если только некоторые ClassN.SomeNumber == SomeNumber, то вы должны сделать это следующим образом:

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

Не этот код такой же, как тот, который я использовал, за исключением того, что у моего кода есть еще 1 линия? –

+0

Нет, поскольку он немедленно возвращается, если числа равны. В вашем коде возможно, что есть правильное число, но оно переопределяется другим предложением if. – LueTm

+0

Он не может быть переопределен, потому что есть предложения 'else', и будет возвращать 0, если ни одно из условий не соответствует. –

Смежные вопросы