dotnet/efcore · error · NotImplementedException

Subquery with index projection binding

Error message

Subquery with index projection binding

What it means

Thrown by the Cosmos SQL translator when a subquery's shaped result exposes its projection by positional index instead of by named ProjectionMember. The provider only knows how to remap member-based projection bindings across subquery boundaries, so this is an unimplemented translation path (NotImplementedException) rather than a configuration error. It is an internal API surface and indicates the Cosmos provider has not yet implemented this query shape.

Source

Thrown at src/EFCore.Cosmos/Query/Internal/CosmosSqlTranslatingExpressionVisitor.cs:455

                if (mappedProjectionBindingExpression == null
                    && shaperExpression is BlockExpression
                    {
                        Expressions: [BinaryExpression { NodeType: ExpressionType.Assign, Right: ProjectionBindingExpression pbe2 }, _]
                    })
                {
                    mappedProjectionBindingExpression = pbe2;
                }

                if (mappedProjectionBindingExpression == null)
                {
                    return QueryCompilationContext.NotTranslatedExpression;
                }

                var subquery = (SelectExpression)shapedQuery.QueryExpression;

                var projection = mappedProjectionBindingExpression.ProjectionMember is { } projectionMember
                    ? subquery.GetMappedProjection(projectionMember)
                    : throw new NotImplementedException("Subquery with index projection binding");
                if (projection is not SqlExpression sqlExpression)
                {
                    return QueryCompilationContext.NotTranslatedExpression;
                }

                if (subquery.Sources.Count == 0)
                {
                    return sqlExpression;
                }

                // TODO TODO
                // subquery.ReplaceProjection(new List<Expression> { sqlExpression });
                subquery.ApplyProjection();

                // Add VALUE to the subquery's projection (SELECT VALUE x ...), to make it project that value rather than a JSON object
                // wrapping that value.
                subquery = subquery.WithSingleValueProjection();

View on GitHub (pinned to 3a2006ef56)

Solutions

  1. Rewrite the query to flatten nested subqueries so the projection is member-based.
  2. Insert AsEnumerable() (or ToListAsync()) before the subquery so it evaluates on the client.
  3. Project scalar members directly inside the subquery instead of through a complex shaper.
  4. File an issue on the dotnet/efcore repo with a minimal repro so the Cosmos team can implement the path.

Example fix

// before
var q = await db.Users
    .Where(u => u.Posts.Select(p => p.Title).Any(t => t.StartsWith("x")))
    .ToListAsync();

// after - move the subquery predicate to the client
var users = await db.Users.ToListAsync();
var q = users
    .Where(u => u.Posts.Select(p => p.Title).Any(t => t.StartsWith("x")))
    .ToList();
Defensive patterns

Strategy: fallback

Validate before calling

// No public API to pre-check; detect unsupported subquery shapes by
// wrapping exploratory queries in try/catch and falling back to AsEnumerable.
public static async Task<List<T>> SafeQuery<T>(IQueryable<T> query)
{
    try { return await query.ToListAsync(); }
    catch (NotImplementedException) { return query.AsEnumerable().ToList(); }
}

Try / catch

try { result = await query.ToListAsync(); }
catch (NotImplementedException ex) when (ex.Message.Contains("Subquery"))
{ result = await query.AsAsyncEnumerable().ToListAsync(); }

Prevention

When it happens

Trigger: Translating a LINQ query where a SelectExpression subquery has an index-based (positional) projection binding (mappedProjectionBindingExpression.ProjectionMember is null). This typically arises from complex nested subqueries, certain GroupBy shapes, or SelectMany patterns where the query compiler builds index-bound shapers.

Common situations: Complex nested subqueries; subqueries introduced by Any/All/Select over navigation collections that fall back to index projection; queries generated by query rewriters that emit positional projection bindings.

Related errors


AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11). Data as JSON: /api/errors/38cb148fa78c1ae9. Report an issue: GitHub.