将 var 更改为 IEnumerable 会产生不同的搜索结果
当我将 var 更改为 IEnumerable 时,我的搜索结果变得区分大小写;考虑下面的代码:
下面的代码返回 RA 或 ra 的两种情况:
var result = from x in dataBase.tableName
select x;
result = result.Where(x => x.id.Contains("ra"));
下面的代码仅返回 ra 的情况而不返回 RA:
IEnumerable result = from x in dataBase.tableName
select x;
result = result.Where(x => x.id.Contains("ra"));
有人可以帮助并解释我发生了什么事吗?结果不应该是相似的吗?
My search result becomes case sensitive when I change var to IEnumerable; consider below code:
the code below returns both cases with RA or ra:
var result = from x in dataBase.tableName
select x;
result = result.Where(x => x.id.Contains("ra"));
the code below returns only cases with ra and not RA:
IEnumerable result = from x in dataBase.tableName
select x;
result = result.Where(x => x.id.Contains("ra"));
Could someone help and explain me what is going on? shouldn't the result be similar?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
发布评论
评论(2)
您的 result
变量不是 IEnumerable
- 它是 IQueryable
。
当您手动将类型更改为 IEnumerable
时,结果会发生变化,因为您现在使用 Linq to Objects 执行以下 Contains
查询,而不是使用 Linq to Entities(或 Linq到 SQL)。
通过 IEnumerable
,您的查询将使用 lambda 表达式,将数据库中的每个结果放入内存并执行区分大小写的 Contains()
扩展方法。
使用 IQueryable
,您的查询将使用表达式树,并将尝试使用您的 Contains
查询创建相应的数据库查询,该查询恰好不区分大小写(很可能是 SQL LIKE
查询)。
只需将隐式类型显式设置为 IQueryable 即可解决您的问题。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
区别在于,在第一种情况下,
var
将是IQueryable
- 这意味着您的Where
调用将是Queryable.Where
(将 lambda 表达式转换为表达式树之后)。过滤器最终在数据库中执行,我怀疑您的字段不区分大小写(因此搜索不区分大小写)。在第二种情况下,您有一个
IEnumerable
,因此您的Where
调用将是Enumerable.Where
(在转换您的委托的 lambda 表达式)。过滤器最终会在 .NET 代码中执行 - 其中Contains
始终区分大小写。基本上,LINQ 是一个有漏洞的抽象 - 是的,如果同一个过滤器在所有情况下都给出相同的结果,那就太好了,但这是不现实的。了解漏洞在哪里,并采取相应的行动 - LINQ 仍然是一个巨大的福音:)
The difference is that in the first case,
var
will be anIQueryable<T>
- which means yourWhere
call will be toQueryable.Where
(after converting your lambda expression to an expression tree). The filter ends up being executed in the database, where I suspect your field is case-insensitive (and so searching is case-insensitive).In the second case, you've got an
IEnumerable<T>
, so yourWhere
call will be toEnumerable.Where
(after converting your lambda expression to a delegate). The filter ends up being executed in .NET code instead - whereContains
is always case-sensitive.Basically, LINQ is a leaky abstraction - yes, it would be lovely if the same filter gave the same results in all situations, but that's unrealistic. Learn where the leaks are, and act accordingly - LINQ is still a huge boon :)