System.InvalidOperationException: The LINQ expression 'x => x.SomeMethod()' 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-translation-failure
Version Compatibility
| Version | Status | Introduced | Deprecated | Notes |
|---|---|---|---|---|
| net6.0 | active | — | — | — |
| net7.0 | active | — | — | — |
| net8.0 | active | — | — | — |
| net9.0 | active | — | — | — |
Root Cause
EF Core cannot translate a LINQ method call (e.g., custom methods, ToString on non-mapped types) into SQL, because it lacks a corresponding SQL function or mapping.
generic中文
EF Core 无法将 LINQ 方法调用(例如自定义方法、未映射类型上的 ToString)转换为 SQL,因为它没有对应的 SQL 函数或映射。
Official Documentation
https://learn.microsoft.com/en-us/ef/core/querying/client-evalWorkarounds
-
90% success 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.
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.
-
85% success 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();'
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();'
-
80% success Register a custom queryable function using 'HasDbFunction' in OnModelCreating. Example: 'modelBuilder.HasDbFunction(() => MyDbContext.ConvertToUpper(default))' and map it to a SQL function like 'UPPER'.
Register a custom queryable function using 'HasDbFunction' in OnModelCreating. Example: 'modelBuilder.HasDbFunction(() => MyDbContext.ConvertToUpper(default))' and map it to a SQL function like 'UPPER'.
中文步骤
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.
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();'
Register a custom queryable function using 'HasDbFunction' in OnModelCreating. Example: 'modelBuilder.HasDbFunction(() => MyDbContext.ConvertToUpper(default))' and map it to a SQL function like 'UPPER'.
Dead Ends
Common approaches that don't work:
-
Adding .AsEnumerable() before the problematic method call without understanding which part causes the issue
75% fail
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.
-
Using .Select() with a lambda that calls ToString() on a non-string property expecting EF Core to translate it
85% fail
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.
-
Changing the method to be static and assuming EF Core will recognize it
90% fail
EF Core does not automatically translate custom static methods; they must be registered as queryable functions or converted to translatable expressions.