多个查询

Mik*_*att 2 c# where-clause linq-to-sql

我需要编写一个将在数据库表上执行关键字搜索的查询.代码目前看起来像这样(尽管有一组硬编码的关键字):

var keywords = new [] { "alpha", "bravo", "charlie" };
IQueryable<Story> stories = DataContext.Stories;

foreach( var keyword in keywords )
{
    stories = from story in stories where story.Name.Contains ( keyword ) );
}

return stories;
Run Code Online (Sandbox Code Playgroud)

ReSharper 在foreach中为关键字抛出"访问修改后的闭包"警告.我理解错误,并在查看生成的SQL时确认问题:

SELECT [t0].[Id], [t0].[Name]
FROM [dbo].[Story] AS [t0]
WHERE (([t0].[Name] LIKE @p0))
  AND (([t0].[Name] LIKE @p1))
  AND (([t0].[Name] LIKE @p2))
-- @p0: Input NVarChar (Size = 9; Prec = 0; Scale = 0) [%charlie%]
-- @p1: Input NVarChar (Size = 9; Prec = 0; Scale = 0) [%charlie%]
-- @p2: Input NVarChar (Size = 9; Prec = 0; Scale = 0) [%charlie%]
-- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.30729.1
Run Code Online (Sandbox Code Playgroud)

因为关键字迭代器在循环期间发生了变化,所以我的SQL只包含对最后一个值("charlie")的引用.

我该怎么做才能避免这个问题?在应用每个新关键字where子句之前,我可以将可查询的故事转换为列表,但这似乎效率低下.

解决了

感谢所有的答案.最终我遇到了两个不同的问题,这两个问题都得到了解决:

  1. 在foreach()循环中使用局部变量以避免"访问修改后的闭包"问题.
  2. 使用LINQKit中的PredicateBuilder动态组合OR子句列表,以允许"任意"式关键字搜索.

tva*_*son 5

将变量分配给foreach块范围内的临时变量,以便每次都获得一个新变量.

foreach( var keyword in keywords )
{
    var kwd = keyword;
    stories = from story in stories where story.Name.Contains ( kwd ) );
}
Run Code Online (Sandbox Code Playgroud)

Eric Lippert有一篇很好的文章(或两篇)解释了在闭包中包含循环变量的危险以及如何避免它.