2013-08-22 159 views
8

我只是想構建一個動態過濾器。 最後返回如何將IQueryable <T>轉換爲表達式<Func <T, bool>>?

Expression<Func<Event, bool>> 

我試圖使用合併(AndAlso)的表達,但它不幹活,最後我發現有這良好的工作IQueryable的查詢,但是現在我如何轉換它的返回類型 -

Expression<Func<Event, bool>>? 

我的代碼:

public IQueryable<Event> GetBySearch(EventFilter search) 
    { 
     IQueryable<Event> query = this.Context.Events.AsQueryable(); 
     Expression<Func<Event, bool>> expression = null; 

     if (search.CategoryId != 0) 
     { 
      query = query.Where(x => x.CategoryId == search.CategoryId); 
     } 

     if (search.SubCategoryId != 0) 
     { 
      query = query.Where(x => x.SubCategoryId == search.SubCategoryId); 
     } 

     expression = query.Expression as Expression<Func<Event, bool>>; //This convert is not working, it returns null. 

     return this.Context.Events.Where(expression); 
    } 
+0

看看更新答案(我認爲你已經接受了它,不知道你是否仍然會通知該情況),這需要考慮Florian的評論。 – Sam

回答

6

任何理由,你不只是做到以下幾點:

public IQueryable<Event> GetBySearch(EventFilter search) 
{ 
    IQueryable<Event> query = this.Context.Events.AsQueryable(); 

    if (search.CategoryId != 0) 
    { 
     query = query.Where(x => x.CategoryId == search.CategoryId); 
    } 

    if (search.SubCategoryId != 0) 
    { 
     query = query.Where(x => x.SubCategoryId == search.SubCategoryId); 
    } 

    return query; 
} 

正如弗洛裏安在評論中所說,返回IQueryables是可以避免的(如果可能的話)。最簡單的辦法是返回一個列表,而不是:

public List<Event> GetBySearch(EventFilter search) 
{ 
    IQueryable<Event> query = this.Context.Events.AsQueryable(); 

    if (search.CategoryId != 0) 
    { 
     query = query.Where(x => x.CategoryId == search.CategoryId); 
    } 

    if (search.SubCategoryId != 0) 
    { 
     query = query.Where(x => x.SubCategoryId == search.SubCategoryId); 
    } 

    return query.ToList(); 
} 
+0

噢,這真的很容易,現在它的工作原理,非常感謝你:) –

+0

這泄漏了尚未評估的IQueryable,然後可能會導致意想不到的結果。由於「搜索」的範圍不固定到「GetBySearch」 - >錯誤實踐 – LunicLynx

+1

@FlorianDohrendorf真。如果你讓函數返回'List '和'return query.ToList()',很容易修復。除非你真的需要IQueryable,否則這將是一條路。我會編輯它。 – Sam

2

這種轉換是無效的,因爲Where將其轉換成MethodCallExpression

這將是有效的:

MethodCallExpression e = query.Expression as MethodCallExpression; 
相關問題