ami*_*t_g 1 c# linq entity-framework entity-framework-4
在对bug进行故障排除时遇到了这个问题.这似乎是由于延迟执行而查询使用的是变量关键字的最后一个值.建议的解决方案是什么?
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();
Run Code Online (Sandbox Code Playgroud)
像这样的查询结果(注意两个参数的值是"Car")
exec sp_executesql N'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''~'')
',N'@p__linq__0 nvarchar(4000),@p__linq__1 nvarchar(4000)',@p__linq__0=N'%Car%',@p__linq__1=N'%Car%'
Run Code Online (Sandbox Code Playgroud)
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'~')
Run Code Online (Sandbox Code Playgroud)
这是由于匿名函数中捕获变量的方式.改变这个:
foreach (var keyword in keywords)
{
query = query.Where(c => c.Name.Contains(keyword));
}
Run Code Online (Sandbox Code Playgroud)
对此:
foreach (var keyword in keywords)
{
var copy = keyword;
query = query.Where(c => c.Name.Contains(copy));
}
Run Code Online (Sandbox Code Playgroud)
它应该工作.有关详细信息,请参阅Eric Lippert的博客文章.C#5的行为正在改变,所以你不必担心这一点.
但请注意,您也可以尝试让LINQ为您执行此操作:
var query = dbContext.Cars.Where(c => keywords.All(key => c.Name.Contains(key));
Run Code Online (Sandbox Code Playgroud)
我很确定这会对Any(有效的"OR")起作用,但我不确定它是否适用All.试一试......
| 归档时间: |
|
| 查看次数: |
657 次 |
| 最近记录: |