2009-08-31 65 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