2013-08-30 142 views
1
courses = courses.Where(
       c => queryParameters.ShowInActive || c.Flags.Contains((ulong)CourseFlags.Active) 
        && 
        (queryParameters.AuthorId <= 0 || 
         (c.Authors != null && c.Authors.Exists(a => a.ID == queryParameters.AuthorId))) 
        && 
        (queryParameters.CategoryIDs == null || queryParameters.CategoryIDs.Count == 0 || 
         (c.Tags != null && c.Tags.Any(t => queryParameters.CategoryIDs.Contains(t.ID))) 
         && 
         queryParameters.CourseIDs == null || queryParameters.CourseIDs.Count == 0 || 
         queryParameters.CourseIDs.Contains(c.ID)) 
       ).ToList(); 

問題是queryParameters.CourseIDS.Count()返回157,但上面的lambda表達式返回2500條記錄。我究竟做錯了什麼?我的lambda表達式不會產生我預期的結果

我也確信,ShowInactive設置爲true和CategoryIDs是零和AuthorId是0

+0

「課程」中有多少個對象/記錄?除了有'Id','Tags'和'Authors'列表,你可以告訴我們關於'courses'中的數據嗎? –

+1

只需重寫此表達式而不使用lambda表達式。它不可讀。使用lambda表達式的主要原因是通過不必聲明具有微不足道的實現的委託(例如需要5行聲明和使用的1班輪)來減少混亂。 – evanmcdonnal

+0

關於標題的說明...您的lambda按照書面形式工作。也許'我的lambda表達式不會產生我期望的結果'是一個更好的標題。 –

回答

1

的問題是圍繞運算符優先級,具體& &比||更高的優先級。因此,請不要在此花費太多,請嘗試以下操作:

courses = courses.Where(
      c => (queryParameters.ShowInActive || c.Flags.Contains((ulong)CourseFlags.Active)) 
       && 
       (queryParameters.AuthorId <= 0 || 
        (c.Authors != null && c.Authors.Exists(a => a.ID == queryParameters.AuthorId))) 
       && 
       ((queryParameters.CategoryIDs == null || queryParameters.CategoryIDs.Count == 0 || 
        (c.Tags != null && c.Tags.Any(t => queryParameters.CategoryIDs.Contains(t.ID)))) 
        && 
        (queryParameters.CourseIDs == null || queryParameters.CourseIDs.Count == 0 || 
        queryParameters.CourseIDs.Contains(c.ID))) 
      ).ToList(); 
+0

我複製並粘貼您的代碼和瞧!可以看到運算符優先級,導致我的問題。 –

3

TL;博士:你忘了一些括號。

正如所寫的,當queryParamters.ShowInActive設置爲true時,謂詞返回true並返回所有記錄。因此,所有記錄都會返回。您似乎想要使用所有查詢參數。爲了清晰起見,請嘗試爲這個複雜的查詢添加一些空格。或者考慮將其拆分爲多個Where()調用。

courses = courses.Where(
       c => (
        queryParameters.ShowInActive 
        || 
        c.Flags.Contains((ulong)CourseFlags.Active) 
      ) && (
        queryParameters.AuthorId <= 0 
        || (
         c.Authors != null 
         && 
         c.Authors.Exists(a => a.ID == queryParameters.AuthorId) 
         ) 
      ) && (
        queryParameters.CategoryIDs == null 
        || 
        queryParameters.CategoryIDs.Count == 0 
        || (
         c.Tags != null 
         && 
         c.Tags.Any(t => queryParameters.CategoryIDs.Contains(t.ID)) 
         ) 
      ) && (
        queryParameters.CourseIDs == null 
        || 
        queryParameters.CourseIDs.Count == 0 
        || 
        queryParameters.CourseIDs.Contains(c.ID) 
        ) 
      ) 
      ).ToList(); 
+3

這是一個複雜的說法:你忘了括號。 –

+0

此外,我想他想括起最後三個(即'(queryParameters.CourseIDs == null || queryParameters.CourseIDs.Count == 0 || queryParameters.CourseIDs.Contains(c.ID))' –

+0

If這是linq to sql,那麼它不會像linq那樣將對象短路。 –

相關問題