LINQ表达式无法翻译,将在本地评估 [英] The LINQ expression could not be translated and will be evaluated locally

查看:415
本文介绍了LINQ表达式无法翻译,将在本地评估的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在EntityFramework Core中得到此警告是什么问题吗?

Im getting this WARNING in EntityFramework Core what is wrong?

我已经将MSSQL Datebase设置为区分大小写.

I already set MSSQL Datebase to Case Sensitive.

Latin1_General_100_CS_AS

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)' 无法翻译,将在本地进行评估.

Microsoft.EntityFrameworkCore.Query:Warning: The LINQ expression 'where [m].LastName.Equals("ALEXANDER", InvariantCultureIgnoreCase)' could not be translated and will be evaluated locally.

推荐答案

您必须了解IEnumerableIqueryable之间的区别.

You have to be aware of the difference between IEnumerable and Iqueryable.

IEnumerable对象表示对象序列.它包含此序列中要枚举的所有内容:您可以要求序列中的第一个元素,一旦有了一个元素,只要存在下一个,您就可以要求下一个.

An IEnumerable object represents a sequence of objects. It holds everything to enumerate over this sequence: you can ask for the first element of the sequence, and once you've got an element you can ask for the next one, as long as there is a next one.

IQueryable对象似乎是IEnumerable,但是它并不表示可枚举的序列,而是表示获得IEnumerable序列的潜力.

An IQueryable object seems like an IEnumerable, however, it does not represent an enumerable sequence, it represents the potential to get an IEnumerable sequence.

IQueryable对象包含一个Expression和一个Provider. Expression是通用描述,表示必须查询的内容. Provider知道谁将执行查询(通常是数据库管理系统),以及使用什么语言与该DBMS通信(通常是SQL).

The IQueryable object holds an Expression and a Provider. The Expression is a generic description expressing what must be queried. The Provider knows who will execute the query (usually a database management system) and what language is used to communicate with this DBMS (usually SQL).

如果您开始枚举IQueryable,或者使用GetEnumeratorMoveNext显式枚举,或者通过调用foreach,ToList,Max,FirstOrDefault等隐式调用,这些枚举将深入调用GetEnumerator和MoveNext,则将表达式发送到提供程序,它将把它转换成SQL并从DBMS中获取数据.提取的数据以IEnumerable的形式返回,其中调用了GetEnumerator和MoveNext.

If you start enumerating an IQueryable, either explicitly using GetEnumerator and MoveNext, or implicitly by calling foreach, ToList, Max, FirstOrDefault, etc, which will deep inside call GetEnumerator and MoveNext, the Expression is sent to the Provider, who will translate it into SQL and fetch the data from the DBMS. The fetched data is returned as an IEnumerable, of which the GetEnumerator and MoveNext are called.

因此,在调用GetEnumerator和MoveNext之前不会执行查询.

So the query is not executed before you call GetEnumerator and MoveNext.

这与我的问题有什么关系?

实体框架只能将类和方法转换为它知道的SQL.实体框架不知道您自己的功能.实际上,实体框架不支持几种LINQ函数.请参阅

Entity framework can only convert classes and methods to SQL that it knows about. Entity Framework does not know your own functions. In fact, there are several LINQ function that are not supported by entity framework. See Supported and Unsupported LINQ methods

String.Equals(string, StringComparison)是不受支持的方法之一.如果使用此函数,则编译器不会抱怨,您将在运行时看到此错误.它告诉您在调用函数之前将首先获取数据. 这可能会导致低效率的行为.

One of the unsupported methods is String.Equals(string, StringComparison). If you use this function, the compiler can't complain, you'll see this error at runtime. It tells you that the data will first be fetched before the function is called. This might lead to inefficient behaviour.

您的LINQ语句等于(忽略异步等待,而不是问题的一部分)

Your LINQ statement is equal to (leave out the async-await, not part of the problem)

var test = dbContext.Students
    .Where(student => student.LastName.Equals("ALEXANDER", StringComparison.InvariantCultureIgnoreCase))
    .FirstOrDefault();

由于不能使用Equals,因此警告指出在执行Where之前在本地获取数据.因此,可能有几个未通过Where的项目将从DBMS转移到您的本地进程.

Since Equals can't be used, the warning says that the data is fetched locally before the Where is executed. So it might be that several items that will not pass the Where will be transferred from the DBMS to your local process.

如果您的数据库可以忽略大小写,请考虑将代码更改为:

If your database can ignore case sensitivity, consider changing your code to:

var test = dbContext.Students
    .Where(student => student.LastName == "ALEXANDER")
    .FirstOrDefault();

这将导致类似于以下内容的SQL语句:

This will result in a SQL statement similar to:

SELECT TOP 1 * from myDatabase.Students where LastName = "ALEXANDER"

(不确定这是否是正确的SQL,因为我使用实体框架,所以我的SQL有点生锈.我想你会明白的)

(not sure if this is correct SQL, since I use entity framework my SQL is a bit rusty. I guess you'll get the gist)

这篇关于LINQ表达式无法翻译,将在本地评估的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆