Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# foreach/for中内置where子句的延迟查询_C#_Linq_Entity Framework_Entity Framework 4 - Fatal编程技术网

C# foreach/for中内置where子句的延迟查询

C# foreach/for中内置where子句的延迟查询,c#,linq,entity-framework,entity-framework-4,C#,Linq,Entity Framework,Entity Framework 4,在对一个bug进行故障排除时,我遇到了这个问题。这似乎是由于延迟执行,查询使用的是variable关键字的最后一个值。解决这个问题的推荐模式是什么 var query = from c in dbContext.Cars select c; var keywords = new string[] { "Clean", "Car" }; foreach (var keyword in keywords) { query = query.Where(c =>

在对一个bug进行故障排除时,我遇到了这个问题。这似乎是由于延迟执行,查询使用的是variable关键字的最后一个值。解决这个问题的推荐模式是什么

var query = from c in dbContext.Cars
            select c;

var keywords = new string[] { "Clean", "Car" };

foreach (var keyword in keywords)
{
    query = query.Where(c => c.Name.Contains(keyword));
}

var cars = query.ToList();
查询结果如下(注意两个参数的值都是“Car”)

在LINQPad中调试也显示相同的查询

DECLARE p__linq__0 NVarChar(1) = '%Car%'
DECLARE p__linq__1 NVarChar(1) = '%Car%'

SELECT 
[Extent1].[CarID] AS [MID], 
[Extent1].[Name] AS [Name], 
FROM [dbo].[Cars] AS [Extent1]
WHERE ([Extent1].[Name] LIKE @p__linq__0 ESCAPE N'~') AND ([Extent1].[Name] LIKE @p__linq__1 ESCAPE N'~')

这是由于匿名函数中捕获变量的方式造成的。更改此项:

foreach (var keyword in keywords)
{
    query = query.Where(c => c.Name.Contains(keyword));
}
为此:

foreach (var keyword in keywords)
{
    var copy = keyword;
    query = query.Where(c => c.Name.Contains(copy));
}
它应该会起作用。有关更多详细信息,请参阅。C#5的行为正在发生变化,因此在这一点上你不必担心

但是,请注意,您也可以尝试让LINQ为您执行以下操作:

var query = dbContext.Cars.Where(c => keywords.All(key => c.Name.Contains(key));

我很确定这对
Any
(一个“或”有效)有效,但我不确定它是否对
All
有效。试试看…

这是由于匿名函数中捕获变量的方式造成的。更改此项:

foreach (var keyword in keywords)
{
    query = query.Where(c => c.Name.Contains(keyword));
}
为此:

foreach (var keyword in keywords)
{
    var copy = keyword;
    query = query.Where(c => c.Name.Contains(copy));
}
它应该会起作用。有关更多详细信息,请参阅。C#5的行为正在发生变化,因此在这一点上你不必担心

但是,请注意,您也可以尝试让LINQ为您执行以下操作:

var query = dbContext.Cars.Where(c => keywords.All(key => c.Name.Contains(key));

我很确定这对
Any
(一个“或”有效)有效,但我不确定它是否对
All
有效。试试看……

谢谢@Jon,它很好用。谢谢Eric的博客链接,因为它解释得很清楚。这是一个相当大的代码中实际查询构建的非常简短的版本,因此我必须确认是否可以使用任何/全部。同样感谢这些。当在实际的查询中使用它们时,它们都可以在一个单独的查询中工作(我已经发布了这个查询),而实际的查询中有其他的连接和条件,EF生成的查询会变得很糟糕,并且永远需要执行。这可能是改变开始的原因,也是一个巨大的变化。坚持使用foreach,在内部创建新的闭包变量。谢谢@Jon,它工作得很好。谢谢Eric的博客链接,因为它解释得很清楚。这是一个相当大的代码中实际查询构建的非常简短的版本,因此我必须确认是否可以使用任何/全部。同样感谢这些。当在实际的查询中使用它们时,它们都可以在一个单独的查询中工作(我已经发布了这个查询),而实际的查询中有其他的连接和条件,EF生成的查询会变得很糟糕,并且永远需要执行。这可能是改变开始的原因,也是一个巨大的变化。坚持使用foreach,在其中创建新的闭包变量。