使用实体框架奇怪的行为在循环中构建查询

发布于 2024-10-24 00:16:58 字数 1211 浏览 3 评论 0原文

我在实体框架存储库上创建了此搜索方法:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

匿名。 2024-10-31 00:16:58

谢谢 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文