dotnet/efcore · error · InvalidOperationException
The LINQ expression '{expression}' could not be translated.
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
Thrown by RelationalProjectionBindingExpressionVisitor (line 131) when an index-based (client-side) projection encounters a ParameterExpression that cannot be translated to SQL. This is EF's generic 'LINQ expression could not be translated' failure: the query contains a construct that has no SQL equivalent, so EF refuses to evaluate it server-side and (without explicit client-evaluation opt-in) aborts. The message directs you to force client evaluation explicitly if that is intended.
Source
Thrown at src/EFCore.Relational/Query/Internal/RelationalProjectionBindingExpressionVisitor.cs:131
case null:
return null;
case not null when _indexBasedBinding:
{
switch (expression)
{
case ConstantExpression:
return expression;
case QueryParameterExpression queryParameterExpression:
return Expression.Call(
GetParameterValueMethodInfo.MakeGenericMethod(queryParameterExpression.Type),
QueryCompilationContext.QueryContextParameter,
Expression.Constant(queryParameterExpression.Name));
case ParameterExpression parameterExpression:
throw new InvalidOperationException(CoreStrings.TranslationFailed(parameterExpression.Print()));
case ProjectionBindingExpression projectionBindingExpression:
return _selectExpression.GetProjection(projectionBindingExpression) switch
{
StructuralTypeProjectionExpression projection => AddClientProjection(projection, typeof(ValueBuffer)),
SqlExpression mappedSqlExpression => AddClientProjection(mappedSqlExpression, expression.Type.MakeNullable()),
// A single-result subquery (e.g. the group element of GroupBy(k).Select(g => g.First()))
// being composed over: lower it into the current select as a to-one join so the result
// has a bindable shape, instead of failing.
ShapedQueryExpression
{
ResultCardinality: ResultCardinality.Single or ResultCardinality.SingleOrDefault
} singleResultSubquery
=> LowerSingleResultSubquery(projectionBindingExpression, singleResultSubquery),
_ => throw new InvalidOperationException(CoreStrings.TranslationFailed(projectionBindingExpression.Print()))
};
case MaterializeCollectionNavigationExpression materializeCollectionNavigationExpression:View on GitHub (pinned to dbf9771522)
Solutions
- Rewrite the projection to use only translatable operations (mapped properties, supported LINQ operators).
- If client evaluation is intended, insert AsEnumerable()/ToListAsync() before the non-translatable part to switch to in-memory.
- Move arbitrary computations out of the IQueryable and apply them after materialization.
- Replace custom method calls with expression-tree-compatible equivalents or raw SQL (FromSqlRaw) where needed.
- Check the linked docs (go.microsoft.com/fwlink/?linkid=2101038) for supported translation patterns.
Example fix
// before - custom method + closure in projection cannot translate
var prefix = GetPrefix();
var q = context.Users.Select(u => FormatLabel(u.Name, prefix)).ToList();
// after - materialize first, then compute client-side
var users = context.Users.Select(u => new { u.Id, u.Name }).AsEnumerable()
.Select(u => FormatLabel(u.Name, prefix)).ToList(); Defensive patterns
Strategy: validation
Validate before calling
// Keep non-translatable logic out of the IQueryable projection.
// Project only mapped properties server-side, then compute client-side.
var server = ctx.Users.Select(u => new { u.Id, u.Name }).AsEnumerable();
var result = server.Select(u => ClientOnly(u.Name)).ToList(); Type guard
// Heuristic: avoid closures/custom methods inside IQueryable Select.
static bool IsTranslatable(Expression e) => e is MemberExpression or BinaryExpression
|| e is MethodCallExpression m && (m.Method.DeclaringType == typeof(EF)
|| m.Method.DeclaringType == typeof(Math) || m.Method.DeclaringType == typeof(string)); Try / catch
try { var q = ctx.Users.Select(u => Client(u.Name)).ToList(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("could not be translated")) {
// Force client evaluation by materializing first.
var data = ctx.Users.Select(u => new { u.Name }).AsEnumerable().Select(u => Client(u.Name)).ToList();
} Prevention
- Avoid closures and custom C# methods inside IQueryable projections.
- Use AsEnumerable()/ToListAsync() to move non-translatable logic client-side.
- Keep projections to mapped properties and supported LINQ operators.
- Review the supported-translation docs before using exotic operators.
When it happens
Trigger: A Select/Where/etc. projection references a parameter or method that cannot be translated to SQL (e.g. a delegate parameter, an unmapped property, calling arbitrary .NET methods in the projection). Triggered specifically in the index-based binding fallback path where a ParameterExpression reaches translation.
Common situations: Projecting a closure variable into the query; calling a custom C# method in Select; referencing a non-mapped property; using .NET APIs with no SQL translation (e.g. complex string/date manipulation); upgrading EF where a previously client-evaluated construct now throws.
Related errors
- The LINQ expression '{expression}' could not be translated.
- The '{methodName}' method is not supported because the query
- The LINQ expression '{expression}' could not be translated.
- The LINQ expression '{expression}' could not be translated.
- The LINQ expression '{expression}' could not be translated.
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/d302b7a23ec66bf7.
Report an issue: GitHub.