2013-02-08 51 views
2

喜有人可以幫助我,我們如何最好可以使用whereif在LINQ如何使用whereif在LINQ

IQueryable<Employee> empQuery; 
    if (empId == "") 
    { 
     empQuery = dbContext.Emps 
      .Include(x => x.Name) 
      .Include(x => x.Code) 
      .Where(x => x.Id == empId); 
    } 
    else 
    { 
     empQuery = dbContext.Emps 
      .Include(x => x.Name) 
      .Include(x => x.Code); 
    } 

我認爲我們可以通過使用whereif右使這個查詢很簡單呢?有人可以幫助我如何通過使用whereif使這個查詢變得簡單嗎?而不是檢查是否(empid ==「」)?

可能嗎?

+0

爲什麼不使用此方法的重載,一個使用'empId',另一個不使用。 – 2013-02-08 12:02:04

+0

我想你是指'if(empId!=「」)'。否則,它不會有很大的意義。 – 2013-02-08 12:11:30

回答

2

我相信你想EMPID過濾,如果它不是空的。簡單或運營商將做的工作:

IQueryable<Employee> empQuery = dbContext.Emps 
      .Include(x => x.Name) 
      .Include(x => x.Code) 
      .Where(x => empId == "" || x.Id == empId); 

您也可以動態地建立查詢:

IQueryable<Employee> empQuery = dbContext.Emps 
      .Include(x => x.Name) 
      .Include(x => x.Code); 

if (empId != "") 
    empQuery = empQuery.Where(x => x.Id == empId); 
+1

我不確定EF是否變得更好(可能),但它用於爲常量表達式生成相當討厭的SQL(例如'empId ==「」'empId已知)。我會選擇第二個選項,這基本上是WhereIf擴展所做的。 – 2013-02-08 12:18:33

+0

@JoachimIsaksson同意,第二種方法在生成的SQL方面更好。順便說一句我不知道爲什麼'empId'參數傳遞兩次,如果我們使用在謂詞WHERE'@ p__linq__0 = N「」「」或[Extent1]。[ID] = @條件p__linq__1'' – 2013-02-08 12:48:13

+0

如果我不得不冒昧猜測,它會太多的工作,並沒有足夠的效果來消除表達式樹枝之間的常見表達式。我只是希望它可以在不將它們傳遞給數據庫的情況下儘可能地摺疊_constant_的分支。 – 2013-02-08 13:01:35

3

我認爲 「whereif」 應該是this extension method。您不能使用它,因爲它在IEnumerable<T>上運行,而不是在IQueryable<T>上運行。其結果是您可以從數據庫請求完整的員工表並在應用程序的內存中執行過濾。這不是你想要的。你可以,但是,使用條件運算符來實現這一點:

var empQuery = dbContext.Emps 
         .Include(x => x.Name) 
         .Include(x => x.Code) 
         .Where(x => empId == "" ? true : x.Id == empId); 

請注意,這是假定你實際上是在你的示例代碼的意思if(empId != "")。如果你沒有這個意思,開關周圍的第二個和第三個操作數:

.Where(x => empId == "" ? x.Id == empId : true); 

話雖如此,你當然可以創建IQueryable<T>相同的擴展方法。它看起來幾乎一樣,只是已經換成IQueryable<T>IEnumerable<T>和謂詞改爲一個表達式:

public static IQueryable<TSource> WhereIf<TSource>(
    this IQueryable<TSource> source, 
    bool condition, 
    Expression<Func<TSource, bool>> predicate) 
{ 
    if (condition) 
     return source.Where(predicate); 
    else 
     return source; 
} 
+0

+1用於修復EF – 2013-02-08 12:08:46

+0

您的第一個查詢與要求相反。不是嗎? – Kaf 2013-02-08 12:13:02

+0

@Kaf:確實,因爲這個要求似乎並不成立。我認爲這是一個簡單的錯字。也請看我對這個問題本身的評論。但是,我更新了我的答案,以便更明確地瞭解它。 – 2013-02-08 12:15:46

0
.Where(x => x.Id == empId); 

無厘頭如果值是「‘’」 - 你能指望什麼它返回?

var query = (from items in dbContext.Emps 
       where items.Id == empId 
       select new { 
          Name = items.Name, 
          Code = items.Code 
       }).ToList();