2017-06-19 38 views
0

的LINQ表達的動態運營商所以我有一個的EntityFramework一個巨大的EntityFramework查詢,但保持它的簡單在這裏一個小例子:C#在的EntityFramework

var amount = 10; 

myArticles.GroupBy(p => p.Id) 
    .Where(grp => grp.Sum(k => k.Amount) > amount 

根據一些參數我< amount== amount

當然,我不希望總是一次寫整個查詢,所以我想出了這個:

Expression<Func<IGrouping<MyEntity, MyXy>, bool>> whereClause; 

,然後根據例如輸入參數:

whereClause = grp => grp.Sum(k => k.Amount) > amount; 
myArticles.GroupBy(p => p.Id) 
    .Where(whereClause); 

現在到問題:是否有可能通過表達式使運算符變爲動態?我想寫的是這樣的:

Expression<Func<decimal, int, bool>> operatorExpression = (arg1, arg2) => arg1 == arg2; 
whereClause = grp => operatorExpression.Invoke(grp.Sum(k => k.Amount), amount); 

據我所知,有LinqKit,但我真的想知道是否有可能解決這個只是用表達式樹,以及如何複雜,它是。我不想在operatorExpression中生成Func,因爲結果應該在SQL Server上計算,而不是在內存中計算。

+0

如果僅使用表達式樹*,則表示沒有自定義表達式處理助手(如LINQKit或類似的)的純C#編譯時表達式,否則不可能。搜索SO for *「撰寫表達式」*,您會發現許多適用於您的簡單案例的示例。 –

+0

你基本上是問LINQKit實現有多困難。你爲什麼不看看它的源代碼並決定自己? – svick

回答

0

不幸的是,您不能.Invoke一個lambda表達式。

語法上,你可以寫

grp => operatorExpression.Compile()(grp.Sum(k => k.Amount), amount) 

它給你一個包含所有信息的表達,但不會被實體框架來理解。

但隨着一些表達操縱這可以轉換爲

grp => <body-of-lambda-with-parameters-replaced-by-corresponding-arguments> 

在你的榜樣,拉姆達的主體爲arg1 == arg2,所以你grp.Sum(k => k.Amount),並arg2amount取代arg1任何ocurrence。

請參閱my other answer包括一些代碼來做到這一點。