2009-08-31 66 views
2

我正在使用Linq和Entity Framework。我有一個頁面實體,它與標籤實體有多對多的關係。使用變量構建Linq表達式

我想要創建一個Linq查詢,該查詢將匹配所有提供的標籤(採用Int64 []形式)的所有頁面。

我已經嘗試過各種WhereIn和BuildContainsExpression示例,但沒有一個按預期工作。

我現在通過每個標籤的努力環和構建表達式的列表:

foreach (Int64 item in Tags) 
{ 
    Expression<Func<Pages, bool>> tagFilter = c => c.Tags.Any(x => x.TagID == item); 
    exp.Add(tagFilter); 
} 

不過,我覺得局部變量「項」與查詢,因爲它搞亂要麼是使用一個標籤,或者他們沒有查詢運行時,但是,如果我指定他們是這樣的:

Expression<Func<Pages, bool>> tagFilter1 = c1 => c1.Tags.Any(x => x.TagID == 70); 
exp.Add(tagFilter1); 
Expression<Func<Pages, bool>> tagFilter2 = c1 => c1.Tags.Any(x => x.TagID == 130); 
exp.Add(tagFilter2); 
Expression<Func<Pages, bool>> tagFilter3 = c1 => c1.Tags.Any(x => x.TagID == 77); 
exp.Add(tagFilter3); 

使用的實際數量「70」爲例,它的工作原理就像一個魅力。我基本上是將表達式存儲在列表中,並使用LinqKit來和()它們。

有沒有辦法保持這種動態?

回答

4

你的代碼更改爲:

foreach (Int64 item in Tags) 
{ 
    var temp = item; // this variable is scoped **inside** the loop. 
    Expression<Func<Pages, bool>> tagFilter = c => c.Tags.Any(x => x.TagID == temp); 
    exp.Add(tagFilter); 
} 

有關詳細說明,read my answer to the "What is the exact definition of a closure?" question

+0

似乎每個人在使用lambda時至少遇到一次這個問題。他們應該真正考慮使它成爲一個編譯器警告,以在foreach中直接使用變量作爲範圍。 – bobbymcr 2009-08-31 00:41:18

+0

非常感謝! – 2009-08-31 16:58:04