dotnet/efcore · error · InvalidOperationException

TranslationFailed

TranslationFailed

Error message

The LINQ expression '{expression}' 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'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.

What it means

The generic translation-failure error. In the TableValuedFunctionQueryRootExpression case (line 114-155) and broadly across query translation, when an expression cannot be translated to SQL and no accumulated error details exist, CoreStrings.TranslationFailed is thrown. It reports the offending expression and points to client-evaluation alternatives (AsEnumerable/ToListAsync).

Source

Thrown at src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs:140

                    {
                        string call;
                        var methodInfo = function.DbFunctions.Last().MethodInfo;
                        if (methodInfo != null)
                        {
                            var methodCall = Expression.Call(
                                // Declaring types would be derived db context.
                                Expression.Default(methodInfo.DeclaringType!),
                                methodInfo,
                                tableValuedFunctionQueryRootExpression.Arguments);

                            call = methodCall.Print();
                        }
                        else
                        {
                            call = $"{function.DbFunctions.Last().Name}()";
                        }

                        throw new InvalidOperationException(
                            TranslationErrorDetails == null
                                ? CoreStrings.TranslationFailed(call)
                                : CoreStrings.TranslationFailedWithDetails(call, TranslationErrorDetails));
                    }

                    arguments.Add(sqlArgument);
                }

                var entityType = tableValuedFunctionQueryRootExpression.EntityType;
                var alias = _sqlAliasManager.GenerateTableAlias(function);
                var translation = new TableValuedFunctionExpression(alias, function, arguments);
                var queryExpression = CreateSelect(entityType, translation);

                return CreateShapedQueryExpression(entityType, queryExpression);
            }

            case EntityQueryRootExpression entityQueryRootExpression
                when entityQueryRootExpression.GetType() == typeof(EntityQueryRootExpression)

View on GitHub (pinned to dbf9771522)

Solutions

  1. Rewrite the query to use only provider-translatable constructs; replace client-side methods with captured parameters or EF.Functions equivalents.
  2. If the operation genuinely must run client-side, insert AsEnumerable()/ToListAsync() before the unsupported operator to force client evaluation.
  3. Map server-side functions via HasDbFunction for reusable SQL functions.
  4. Simplify the query and add pieces back incrementally to isolate the untranslatable fragment.

Example fix

// before (client-side method in Where)
var active = db.Users.Where(u => Helper.IsActive(u.Status)).ToList();

// after (capture the value as a parameter, or translate the predicate)
var activeStatus = Helper.ActiveStatusValue;
var active = db.Users.Where(u => u.Status == activeStatus).ToList();
// or force client evaluation explicitly:
var active = db.Users.AsEnumerable().Where(u => Helper.IsActive(u.Status)).ToList();
Defensive patterns

Strategy: try-catch

Try / catch

try { var r = await query.ToListAsync(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("could not be translated"))
{ /* isolate the untranslatable fragment; rewrite or move client-side with AsEnumerable */ }

Prevention

When it happens

Trigger: A LINQ query (including TVF argument translation) containing a construct the provider cannot turn into SQL: a client-side method, an unsupported operator, a C# feature with no SQL equivalent, or an unmapped member — and no detailed sub-errors were collected.

Common situations: Calling custom methods or static helpers in Where/Select; using unsupported date/string operations; referencing properties not in the model; provider limitations (e.g. certain functions on SQLite); LINQ that worked on one provider failing on another.

Related errors


AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06). Data as JSON: /api/errors/f42b6a7a9fbfd798. Report an issue: GitHub.