dotnet/efcore · error · InvalidOperationException
The LINQ expression ' ' could not be translated. Either…
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 InMemoryProjectionBindingExpressionVisitor maps each ProjectionBindingExpression to a server-side projection slot. When the mapped projection is neither an EntityProjectionExpression nor an InMemoryQueryExpression, the visitor cannot produce a shaper for it and throws TranslationFailed. This indicates a projection element that has no server-side representation in the InMemory provider.
Solutions
- Identify the expression fragment named in the error message and rewrite the Select to use only translatable constructs (mapped properties, arithmetic, supported methods).
- Insert AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync() before the Select to force that projection to run client-side.
- If the projection wraps a collection navigation, ensure it is shaped as a subquery rather than a raw method call.
- Simplify the Select to the minimal shape and add complexity incrementally to isolate the un-translatable fragment.
Example fix
// before — Reverse has no server translation in InMemory
var result = ctx.Blogs
.Select(b => new { b.Title, Tags = b.Tags.Reverse().ToList() });
// after — materialize first, then project client-side
var result = ctx.Blogs
.AsEnumerable()
.Select(b => new { b.Title, Tags = b.Tags.Reverse().ToList() }); Defensive patterns
Strategy: try-catch
Validate before calling
// There is no pre-flight API to detect un-translatable projections. // Strategy: isolate complex projections and test them; fall back to client eval. // Use a try/catch around query execution and retry with AsEnumerable if translation fails. IQueryable<T> SafeQuery<T>(IQueryable<T> q) => q; // placeholder — real guard is structural review
Try / catch
try
{
return await query.ToListAsync(cancellationToken);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("could not be translated"))
{
// Fall back: materialize server-side, then apply the problematic projection client-side
logger.LogWarning("Server translation failed; switching to client evaluation.");
var serverData = baseQuery.AsEnumerable();
return clientProjection(serverData).ToList();
} Prevention
- Keep Select projections simple — only mapped properties and supported methods.
- If a projection needs a CLR method, insert AsEnumerable() before the Select.
- Write integration tests for each query to catch translation failures early.
- Avoid mixing custom helper method calls into server-side LINQ expressions.
When it happens
Trigger: A LINQ Select whose projection contains an expression the InMemory provider cannot translate — e.g. calling a custom method, using a property that is not mapped, or embedding a non-translatable sub-expression in the projected shape. The throw happens at query-compilation time when the projection binding visitor walks the Select tree.
Common situations: Calling a CLR method inside Select that has no EF translation (e.g. .Select(x => MyHelper(x.Name))), projecting a computed expression involving unsupported constructs, or upgrading EF Core and hitting a previously-tolerated client-eval path that is now strict.
Related errors
- The LINQ expression ' ' could not be translated. Additional…
- Unable to translate set operation after client projection…
- 'DefaultIfEmpty' cannot be applied after a client-evaluated…
- The operation 'ExecuteDelete' requires an entity type which…
- Using 'Distinct' operation on a projection containing a…
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/a2c39fdc4119dec6.
Report an issue: GitHub.
Appendix: source
Thrown at src/EFCore.InMemory/Query/Internal/InMemoryProjectionBindingExpressionVisitor.cs:117
{
switch (expression)
{
case ConstantExpression:
return expression;
case ProjectionBindingExpression projectionBindingExpression:
var mappedProjection = _queryExpression.GetProjection(projectionBindingExpression);
if (mappedProjection is EntityProjectionExpression entityProjection)
{
return AddClientProjection(entityProjection, typeof(ValueBuffer));
}
if (mappedProjection is not InMemoryQueryExpression)
{
return AddClientProjection(mappedProjection, expression.Type.MakeNullable());
}
throw new InvalidOperationException(CoreStrings.TranslationFailed(projectionBindingExpression.Print()));
case MaterializeCollectionNavigationExpression materializeCollectionNavigationExpression:
{
var subquery = _queryableMethodTranslatingExpressionVisitor.TranslateSubquery(
materializeCollectionNavigationExpression.Subquery)!;
_clientProjections!.Add(subquery.QueryExpression);
return new CollectionResultShaperExpression(
new ProjectionBindingExpression(
_queryExpression, _clientProjections.Count - 1, typeof(IEnumerable<ValueBuffer>)),
subquery.ShaperExpression,
materializeCollectionNavigationExpression.Navigation,
materializeCollectionNavigationExpression.Navigation.ClrType.GetSequenceType());
}
case MethodCallExpression methodCallExpression:
if (methodCallExpression.Method.IsGenericMethod
&& methodCallExpression.Method.DeclaringType == typeof(Enumerable)
&& methodCallExpression.Method.Name == nameof(Enumerable.ToList)View on GitHub (pinned to 3a2006ef56)