# System.InvalidOperationException: LINQ 表达式 'x => x.SomeMethod()' 无法转换。请重写查询为可转换的形式，或通过插入对 'AsEnumerable'、'AsAsyncEnumerable'、'ToList' 或 'ToListAsync' 的调用来显式切换到客户端评估。

- **ID:** `dotnet/ef-core-translation-failure`
- **领域:** dotnet
- **类别:** data_error
- **验证级别:** ai_generated
- **修复率:** 85%

## 根因

EF Core 无法将 LINQ 方法调用（例如自定义方法、未映射类型上的 ToString）转换为 SQL，因为它没有对应的 SQL 函数或映射。

## 版本兼容性

| 版本 | 状态 | 引入 | 弃用 |
|------|------|------|------|
| net6.0 | active | — | — |
| net7.0 | active | — | — |
| net8.0 | active | — | — |
| net9.0 | active | — | — |

## 解决方案

1. ```
   Rewrite the query to use translatable constructs. For example, replace '.Where(x => x.CustomMethod() == value)' with '.Where(x => x.Property == value)' if CustomMethod just accesses a property. If using ToString, use 'SqlFunctions.StringConvert' for numeric types or 'EF.Functions.DateDiff' for dates.
   ```
2. ```
   Use client evaluation explicitly by calling .AsEnumerable() or .ToList() before the non-translatable part. Example: 'var results = context.Entities.Where(e => e.IsActive).AsEnumerable().Where(e => e.CustomMethod() == true).ToList();'
   ```
3. ```
   Register a custom queryable function using 'HasDbFunction' in OnModelCreating. Example: 'modelBuilder.HasDbFunction(() => MyDbContext.ConvertToUpper(default))' and map it to a SQL function like 'UPPER'.
   ```

## 无效尝试

- **Adding .AsEnumerable() before the problematic method call without understanding which part causes the issue** — AsEnumerable() forces client evaluation for the entire query, which may work but can cause performance issues and does not fix the root cause if the method is used multiple times. (75% 失败率)
- **Using .Select() with a lambda that calls ToString() on a non-string property expecting EF Core to translate it** — ToString() is not translatable for many types (e.g., decimal, DateTime) in older EF Core versions; it requires a specific SQL function like CAST or FORMAT. (85% 失败率)
- **Changing the method to be static and assuming EF Core will recognize it** — EF Core does not automatically translate custom static methods; they must be registered as queryable functions or converted to translatable expressions. (90% 失败率)
