System.InvalidOperationException: LINQ 表达式 'DbSet<X>.Where(x => x.Property.Contains("value") || x.OtherProperty.Contains("other"))' 无法翻译。请以可翻译的形式重写查询,或通过插入对 'AsEnumerable'、'AsAsyncEnumerable'、'ToList' 或 'ToListAsync' 的调用来显式切换到客户端评估。
System.InvalidOperationException: The LINQ expression 'DbSet<X>.Where(x => x.Property.Contains("value") || x.OtherProperty.Contains("other"))' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'.
ID: dotnet/ef-core-query-cannot-be-translated-into-a-sql-expression
版本兼容性
| 版本 | 状态 | 引入 | 弃用 | 备注 |
|---|---|---|---|---|
| Entity Framework Core 7.0 | active | — | — | — |
| Entity Framework Core 8.0 | active | — | — | — |
| Microsoft.EntityFrameworkCore.SqlServer 8.0.0 | active | — | — | — |
根因分析
当 LINQ 表达式使用数据库提供程序不支持的某些字符串方法、自定义函数或复杂逻辑等构造时,Entity Framework Core 无法将其翻译为 SQL。
English
Entity Framework Core cannot translate a LINQ expression into SQL when it uses unsupported constructs like certain string methods, custom functions, or complex logic that the database provider does not support.
官方文档
https://learn.microsoft.com/en-us/ef/core/querying/client-evaluation#client-evaluation解决方案
-
仅使用数据库支持的构造重写 LINQ 表达式。例如,将 'x.Property.Contains("value") || x.OtherProperty.Contains("other")' 替换为 'EF.Functions.Like(x.Property, "%value%") || EF.Functions.Like(x.OtherProperty, "%other%")',这会翻译为 SQL LIKE。 -
如果无法重写查询,则显式使用客户端评估,但首先在服务器端尽可能过滤。例如:'var filtered = await context.Orders.Where(o => o.Status == "Active").ToListAsync(); var result = filtered.Where(o => o.Description.Contains("keyword")).ToList();'
无效尝试
常见但无效的做法:
-
75% 失败
Calling 'ToList()' before the filter forces client evaluation but loads all data into memory, causing performance issues and potential out-of-memory errors.
-
80% 失败
Adding 'AsEnumerable()' at the start of the query chain also forces full client evaluation, defeating the purpose of database filtering.
-
90% 失败
Ignoring the error and assuming the query works on a different database provider (e.g., SQLite vs SQL Server) leads to runtime failures when deploying.