2012-04-26 92 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