我们可以在 LINQ to SQL 中使用 ToLowerInvariant() 吗?
我有一种使用DBContext和EF Core检索餐厅表结果的方法:
public IEnumerable<Restaurant> GetRestaurantByName(string? name = null)
{
if (string.IsNullOrEmpty(name))
{
return _dbContext.Restaurants;
}
else
{
return _dbContext.Restaurants
.Where(r => r.Name.ToLower().Contains(name.ToLowerInvariant()));
}
}
问题是当我尝试使用r.name.tolowerinvariant()
而不是r.name时,问题是。 tolower()
我捕获了一个例外,其中包含以下详细信息:
无效的exception:linq表达式'dbset() 。
我喜欢理解场景背后的确切原因和逻辑。
I have a method to retrieve Restaurant table results using DbContext and EF Core with the following code:
public IEnumerable<Restaurant> GetRestaurantByName(string? name = null)
{
if (string.IsNullOrEmpty(name))
{
return _dbContext.Restaurants;
}
else
{
return _dbContext.Restaurants
.Where(r => r.Name.ToLower().Contains(name.ToLowerInvariant()));
}
}
The problem is when I try to use r.Name.ToLowerInvariant()
instead of r.Name.ToLower()
I catch an exception with the following detail:
InvalidOperationException: The LINQ expression 'DbSet()
.Where(r => r.Name.ToLowerInvariant().Contains(__ToLowerInvariant_0))' could not be translated.
I like to understand the exact reason and logic behind the scene.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您需要欣赏EFC是翻译人员。它查看您已构建的LINQ查询,并将其逐个转换为SQL,然后
在说:
它变成:
当您说:
它变为:
这两个可能的功能相同时,它将运行SQL; C#是案例敏感的,但SQL Server可能不是(默认情况下它使用不敏感的整理),因此,即使C#看起来像是胡说八道:
SQLServer处于不敏感的模式下会运行它并返回结果:
您必须保持意识到事实。您的c#被翻译成另一种语言,并根据该语言的规则运行,而不是C#,
如果您想查看查询的内容,请不要运行它:
现在指向
q
在调试器中检查debugview- efc将告诉您它生成的SQL(EFC5+功能)现在记住,我们说这是翻译练习-EFC只能翻译
如果您使LINQ太复杂,您也会遇到错误;您必须找到另一种编写可以翻译的LINQ,或将命中率调整并下载到C#并在此处处理的LINQ
You need to appreciate that EFC is a translator. It looks at the LINQ query you have built and translates it piece by piece into SQL, then it runs the SQL
When you say:
It becomes:
When you say:
It becomes:
These two probably function the same anyway; C# is case sensitive but SQL Server probably isn't (by default it uses insensitive collation) so even though the C# looks like nonsense:
SQLServer in insensitive mode will run it and return results:
You have to remain conscious of the fact that your C# is translated into another language and run according to the rules of that language, not C#
If you want to see what your query becomes, don't run it:
Now point to
q
in the debugger and inspect the DebugView- EFC will tell you what SQL it generates (EFC5+ feature)Now remember we said it's a translation exercise - EFC can only translate what it knows - that's for sql server, different providers translate differently. If you use a function that it doesn't know, like ToLowerInvariant, you get an error. No one at Microsoft(or whoever wrote the provider you're using) has ever sat down and worked out a way to convert ToLowerInvariant into SQL in a meaningful way.
If you make your LINQ too complex you also get an error; you have to find another way to write the LINQ that can be translated, or take the hit and download a (?huge) amount of data into C# and process it there
这是我一直困扰且难以调试的问题。在使用 DB 内的函数时,where 函数在某种程度上受到限制。
这是一个示例:
如果您尝试调用这些针对 DB 的 where 语句内的函数,也会发生同样的事情
如果您尝试将 HasItems 设为仅 Getter 属性会怎样?
因此,只要您尝试调用的函数或列未在数据库服务器中注册,并且查询将在数据库服务器内部运行,就会抛出异常。但是,如果您对应用程序中可用的数据使用相同的查询,它们就会正常工作。
This is a problem that I always suffer from and hard to debug. The where function is somehow limited when it comes to using Functions inside DB.
Here is an example:
and the same thing happens if you try to call functions inside these where statements that work against DB
What if you try to make HasItems as Getter Property Only?
So as long as functions or columns you try to call are not registered in the DB Server, and the query will work inside the DB Server, it will throw an exception. But if you use the same queries with data that are available in the app, they will work just fine.