2012-04-26 41 views
6

我使用带有POCO的EntityFramework。
假设我有波苏斯像这样(简化)的定义:带有多条件的WHERE子句的LINQ查询

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记录,属于一个非此即彼的Class1Class2Class3其中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.Class1x.Class2x.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到实体应执行自动空合并。

回答

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之前测试null值,但不需要,如果您通过Linq-to-entities在SQL中评估SomeNumber。 Linq-to-entities应该执行自动的空合并。

+0

其实溶液(我通常会发现它自己,我问后不久),由于延迟加载禁用,我必须在运行'Where'子句之前执行'var result = DB.SomeClass.Include(“Class1”).include(“Class2”).include(“Class3”)''。然而,我认为这是被接受的,因为你教会了我如何改进我的代码(直接在LINQ-To-Entities中使用'Where') – 2012-04-26 13:30:26

2

根据你的逻辑,如果x.Class1不为null,但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个代码线? – 2012-04-26 13:28:25

+0

不,因为如果数字相同,它会立即返回。在你的代码中,有可能存在一个正确的数字,但它会被另一个if子句覆盖。 – LueTm 2012-04-26 14:31:47

+0

它不能被覆盖,因为有'else'子句,并且如果没有条件匹配,它将返回0。 – 2012-04-27 06:40:25