2014-09-25 34 views
0

我有一個謂語建設者和它工作正常組合兩種不同PredicateBuilders使用表達式

var filter = sortKeys.Aggregate(filter, (currentFilter, sortkey) => currentFilter.Or(
          x => x.Appointments.Any(y => y.RowStatus == Constants.CurrentRowStatus))); 

我現在試圖分裂這是任命內到另一個謂詞建設者,這樣我可以補充條件的條件在旅途中重複使用該功能。

我曾試圖創建一個表達式,然後在主謂詞助洗劑使用它,但它未能

private static Expression<Func<Appointment, bool>> TmpApt(string status) 
    { 
     var predicate = PredicateBuilder.False<Appointment>(); 

     predicate = predicate.Or(p => p.RowStatus == status); 

     return predicate; 
    } 

更改主謂詞使用上述表達式

var filter = sortKeys.Aggregate(PredicateBuilder.True<Person>(), (current, s) => 
           current.Or(x => x.Appointments.Any(TmpApt(s)))); 

它示出一個錯誤,

參數類型'System.Linq.Expressions.Expression<System.Func<Appointment,bool>>'是 不可分配e到參數類型System.Func<Appointment,bool>

我甚至試過LinqKit擴展方法就像展開但可以找到解決方案。

還曾試圖Reusable predicate expressions in LINQ,那麼它沒有顯示在編譯但是當應用程序方面,它顯示用於查詢操作「Any

不支持過載的任何錯誤。

任何人都可以請幫助我如何解決錯誤或提出一種替代解決方案。

回答

1

您可以使用LINQKit調用,你必須在你想要的位置的表達,使用它:

var predicate = TmpApt(); 
var filter = sortKeys.Aggregate(PredicateBuilder.False<Person>(), 
    (current, s) => current.Or(x => 
     x.Appointments.Any(appointment => predicate.Invoke(appointment)))) 
     .Expand(); 

請注意,你需要拉TmpApt伸到一個變量LINQKit成功評估它,由於其實施中的錯誤。

另請注意,由於True或任何東西都是true,所以您需要將聚合操作初始化爲False

另外請注意,您可以簡化TmpApt實施,只是下面:

private static Expression<Func<Appointment, bool>> TmpApt() 
{ 
    return p => p.RowStatus == Constants.CurrentRowStatus; 
} 

沒有必要使用謂詞生成器來OrFalse這裏。

+0

非常感謝...您的解決方案運行良好,但我現在有一個新問題..我想將參數傳遞給TmpApt()。參數值來自「s」(它在聚合中)。當我們將它聲明爲一個變量並調用它時,我不知道該如何傳遞。有沒有解決這個問題的方法。我也會更新主要問題。我很抱歉,這是我的錯誤。 T.讓問題變得簡單我已經刪除了該方法的變量。非常感謝您的幫助和時間。 – Rocky 2014-09-25 17:02:48

+0

@Rocky那麼最簡單的選擇是將'TmpApt'重構爲'Aggregate' lambda。它不能在編譯爲表達式的lambda中,除非你想首先修復LINQKit中的錯誤,這當然是可能的,但並不簡單。 – Servy 2014-09-25 17:06:35