C# 无法翻译LINQ表达式,将在本地对其求值
我在EntityFramework Core中收到此警告有什么问题 我已经将MSSQL数据库设置为区分大小写 拉丁语1\u通用\u 100\u CS\u ASC# 无法翻译LINQ表达式,将在本地对其求值,c#,sql-server,entity-framework,linq,entity-framework-core,C#,Sql Server,Entity Framework,Linq,Entity Framework Core,我在EntityFramework Core中收到此警告有什么问题 我已经将MSSQL数据库设置为区分大小写 拉丁语1\u通用\u 100\u CS\u AS var test = await _context.Students .FirstOrDefaultAsync(m => m.LastName.Equals("ALEXANDER", StringComparison.InvariantCultureIgnoreCase)); Microsoft.E
var test = await _context.Students
.FirstOrDefaultAsync(m => m.LastName.Equals("ALEXANDER", StringComparison.InvariantCultureIgnoreCase));
Microsoft.EntityFrameworkCore.Query:警告:LINQ表达式
'其中[m].LastName.Equals(“ALEXANDER”,不变量文化识别码)'
无法翻译,将在本地进行评估
EntityFramework无法将
Equals(“ALEXANDER”,StringComparison.InvariantCultureIgnoreCase)
转换为SQL,因此,它会将所有Students表加载到内存中,然后搜索满足等式的第一个条目。您必须了解IEnumerable
和Iqueryable
之间的区别
IEnumerable
对象表示一系列对象。它包含了这个序列中要枚举的所有内容:您可以请求序列中的第一个元素,一旦获得了一个元素,您就可以请求下一个元素,只要还有下一个元素
一个IQueryable
对象看起来像是一个IEnumerable,但是,它并不表示一个可枚举序列,它表示获得IEnumerable序列的可能性
IQueryable对象包含一个表达式
和一个提供程序
。表达式
是表示必须查询的内容的通用描述。提供者
知道谁将执行查询(通常是数据库管理系统)以及使用什么语言与该DBMS通信(通常是SQL)
如果开始枚举IQueryable,显式使用GetEnumerator
和MoveNext
,或隐式调用foreach、ToList、Max、FirstOrDefault等,这将深入调用GetEnumerator和MoveNext,表达式将发送到提供程序,谁将把它翻译成SQL并从DBMS中获取数据。获取的数据作为IEnumerable返回,其中调用了GetEnumerator和MoveNext
因此,在调用GetEnumerator和MoveNext之前不会执行查询
这与我的问题有什么关系?
实体框架只能将它知道的类和方法转换为SQL。实体框架不知道自己的功能。事实上,实体框架不支持几个LINQ函数。看
不支持的方法之一是String.Equals(String,StringComparison)
。如果使用此函数,编译器不会抱怨,因为编译器不知道您的entity framework版本支持哪些函数。因此,您不会在编译时看到此错误,而是在运行时看到
该错误告诉您在调用函数之前将首先获取数据。
这可能会导致效率低下的行为
您的LINQ语句等于(省略异步等待,而不是问题的一部分)
由于不能使用Equals,因此警告表示在执行Where之前在本地获取数据。因此,可能会有几个无法通过Where的项从DBMS传输到本地进程
如果数据库可以忽略大小写敏感度,请考虑将代码更改为:
var test = dbContext.Students
.Where(student => student.LastName == "ALEXANDER")
.FirstOrDefault();
这将产生类似以下内容的SQL语句:
SELECT TOP 1 * from myDatabase.Students where LastName = "ALEXANDER"
(不确定这是否是正确的SQL,因为我使用的是实体框架,我的SQL有点生疏。我想你会明白要点)代码可以计算成SQL,这样it将在本地(即应用程序运行的地方)执行比较@Scrobi不能*你只是重新表述了异常消息,这不是解决方案。是的,但op确认了东西被加载到内存中。
SELECT TOP 1 * from myDatabase.Students where LastName = "ALEXANDER"