Aor*_*337 16 c# linq sql-server entity-framework entity-framework-core
我在 EntityFramework Core 中收到此警告,有什么问题?
我已经将 MSSQL 数据库设置为区分大小写。
Latin1_General_100_CS_AS
var test = await _context.Students
                .FirstOrDefaultAsync(m => m.LastName.Equals("ALEXANDER", StringComparison.InvariantCultureIgnoreCase));
Microsoft.EntityFrameworkCore.Query:警告:LINQ 表达式 'where [m].LastName.Equals("ALEXANDER", InvariantCultureIgnoreCase)' 无法翻译,将在本地进行评估。
Har*_*lse 34
你必须要知道之间的差异IEnumerable和Iqueryable。
一个IEnumerable对象代表一个对象序列。它包含要枚举这个序列的所有内容:您可以请求序列的第一个元素,一旦获得了一个元素,您就可以请求下一个元素,只要有下一个元素即可。
一个IQueryable对象看起来像一个 IEnumerable,然而,它并不代表一个可枚举的序列,它代表了获得一个 IEnumerable 序列的可能性。
IQueryable 对象包含 anExpression和 a Provider。这Expression是一个通用描述,表示必须查询的内容。该Provider知道谁将会执行查询(通常是一个数据库管理系统)和语言则使用该数据库管理系统(通常是SQL)沟通一下。
如果您开始枚举 IQueryable,或者显式使用GetEnumeratorand MoveNext,或者通过调用 foreach、ToList、Max、FirstOrDefault 等隐式调用 GetEnumerator 和 MoveNext 等,则表达式将发送到提供程序,提供程序将其转换为 SQL 和从 DBMS 中获取数据。获取的数据作为 IEnumerable 返回,其中调用 GetEnumerator 和 MoveNext。
因此,在调用 GetEnumerator 和 MoveNext 之前不会执行查询。
这和我的问题有什么关系?
实体框架只能将类和方法转换为它知道的 SQL。实体框架不知道您自己的功能。事实上,有几个 LINQ 函数是实体框架不支持的。请参阅支持和不支持的 LINQ 方法
不受支持的方法之一是String.Equals(string, StringComparison). 如果你使用这个函数,编译器不会抱怨,因为编译器不知道你的实体框架版本支持哪些函数。因此你不会在编译时看到这个错误,你会在运行时看到它。
该错误告诉您将在调用函数之前首先获取数据。这可能会导致低效的行为。
您的 LINQ 语句等于(省略异步等待,不是问题的一部分)
var test = dbContext.Students
    .Where(student => student.LastName.Equals("ALEXANDER", StringComparison.InvariantCultureIgnoreCase))
    .FirstOrDefault();
    
由于不能使用 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 有点生疏。我想你会明白要点)
EntityFramework 无法转换Equals("ALEXANDER", StringComparison.InvariantCultureIgnoreCase)为 SQL,因此它会将所有 Students 表加载到内存中,然后搜索满足相等性的第一个条目。
| 归档时间: | 
 | 
| 查看次数: | 26201 次 | 
| 最近记录: |