使用实体框架奇怪的行为在循环中构建查询
我在实体框架存储库上创建了此搜索方法:
public IEnumerable<Person> GetPersonsWithFilter(string filter)
{
var items =
filter.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
var query = _personRepo.All(); // Return IQueryable<Person>
foreach (var item in items)
{
query = query.Where(i => i.SearchName.Contains(item.ToLower()));
}
query.TraceSql(i => Logger.Error(i));
return query.Take(50);
}
TraceSql 输出生成的 sql。如果我的过滤器是“John Landheer”,则会正确生成 sql:
SELECT [Extent1].[PersonId] AS [PersonId] // Other fields deleted for readability
FROM [dbo].[Person] AS [Extent1]
WHERE
(( CAST(CHARINDEX(LOWER(@p__linq__0), [Extent1].[SearchName]) AS int)) > 0)
AND
(( CAST(CHARINDEX(LOWER(@p__linq__1), [Extent1].[SearchName]) AS int)) > 0)
但是,参数是相同的:@p_linq_0 = 'landheer' 和 @p_linq_1 = 'landheer'
现在,如果我将循环更改为:
foreach (var item in items)
{
var tempItem = item;
query = query.Where(i => i.SearchName.Contains(tempItem.ToLower()));
}
一切正常?!?!
我认为这与 EF 构建表达式树的方式有关,但看起来有点意外。有人能解释一下吗?
约翰
I made this search method on my Entity Framework repo:
public IEnumerable<Person> GetPersonsWithFilter(string filter)
{
var items =
filter.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
var query = _personRepo.All(); // Return IQueryable<Person>
foreach (var item in items)
{
query = query.Where(i => i.SearchName.Contains(item.ToLower()));
}
query.TraceSql(i => Logger.Error(i));
return query.Take(50);
}
The TraceSql outputs the resulting sql. If my filter is "John Landheer", the sql is correctly generated:
SELECT [Extent1].[PersonId] AS [PersonId] // Other fields deleted for readability
FROM [dbo].[Person] AS [Extent1]
WHERE
(( CAST(CHARINDEX(LOWER(@p__linq__0), [Extent1].[SearchName]) AS int)) > 0)
AND
(( CAST(CHARINDEX(LOWER(@p__linq__1), [Extent1].[SearchName]) AS int)) > 0)
BUT, the parameters are the same: @p_linq_0 = 'landheer' and @p_linq_1 = 'landheer'
Now, if I change the loop to this:
foreach (var item in items)
{
var tempItem = item;
query = query.Where(i => i.SearchName.Contains(tempItem.ToLower()));
}
Everything works?!?!
I assume it has something to do with the way EF builds an expression tree, but it looks a bit unexpected. Can anybody shed some light on this?
John
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
谢谢 Equiso,我没有找到你提到的问题。所以这是 foreach 循环中内置的 Linq 查询始终采用上次迭代的参数值。
Thanks Equiso, I didn't find the question you refered to. So this is an exact duplicate of Linq query built in foreach loop always takes parameter value from last iteration.