在EntityFramework Core中得到此警告是什么问题?
我已经将MSSQL Datebase设置为区分大小写。
Latin1_General_100_CS_AS
var test = await _context.Students
.FirstOrDefaultAsync(m => m.LastName.Equals("ALEXANDER", StringComparison.InvariantCultureIgnoreCase));
Microsoft.EntityFrameworkCore.Query:警告:LINQ表达式 '其中[m] .LastName.Equals(“ ALEXANDER”,InvariantCultureIgnoreCase)' 无法翻译,将在本地进行评估。
答案 0 :(得分:2)
EntityFramework无法将var selectedIndexPaths: Set<String> = []
override func tableView(_ tableView: UITableView, cellForRowAt
indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "testcell",
for: indexPath)
if selectedIndexPaths.contains(indexPath.description) {
cell.accessoryType = .checkmark
} else {
cell.accessoryType = .none
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath:
IndexPath) {
selectedIndexPaths.insert(indexPath.description)
tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark
}
override func tableView(_ tableView: UITableView, didDeselectRowAt
indexPath: IndexPath) {
selectedIndexPaths.remove(indexPath.description)
tableView.cellForRow(at: indexPath)?.accessoryType = .none
}
转换为SQL,因此它将所有的Student表加载到内存中,然后搜索满足相等性的第一个条目。
答案 1 :(得分:0)
您必须了解IEnumerable
和Iqueryable
之间的区别。
IEnumerable
对象代表一系列对象。它包含要枚举此序列的所有内容:您可以要求序列的第一个元素,一旦有了一个元素,只要有下一个,就可以要求下一个。
IQueryable
对象似乎是IEnumerable,但是它并不表示可枚举的序列,而是表示将返回可枚举序列的查询。
IQueryable对象包含一个Expression
和一个Provider
。 Expression
是一般性描述,必须查询什么。 Provider
知道谁将执行查询(通常是数据库管理系统),以及使用什么语言与该DBMS通信(通常是SQL)。
如果您开始枚举IQueryable,则可以显式使用GetEnumerator
和MoveNext
,或者通过调用foreach,ToList,Max,FirstOrDefault等隐式调用,这些将深入调用GetEnumerator和MoveNext,即表达式发送给提供程序,该提供程序将其转换为SQL并从DBMS中获取数据。提取的数据以IEnumerable的形式返回,其中调用了GetEnumerator和MoveNext。
因此,在调用GetEnumerator和MoveNext之前不会执行查询。
这与我的问题有什么关系?
实体框架只能将类和方法转换为它知道的SQL。实体框架不知道您自己的功能。实际上,实体框架不支持几种LINQ函数。参见Supported and Unsupported LINQ methods
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有点生锈。我想你会明白的)