{"record":{"id":"38cb148fa78c1ae9","repo":"dotnet/efcore","slug":"subquery-with-index-projection-binding","errorCode":null,"errorMessage":"Subquery with index projection binding","messagePattern":"Subquery with index projection binding","errorType":"exception","errorClass":"NotImplementedException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Cosmos/Query/Internal/CosmosSqlTranslatingExpressionVisitor.cs","lineNumber":455,"sourceCode":"                if (mappedProjectionBindingExpression == null\n                    && shaperExpression is BlockExpression\n                    {\n                        Expressions: [BinaryExpression { NodeType: ExpressionType.Assign, Right: ProjectionBindingExpression pbe2 }, _]\n                    })\n                {\n                    mappedProjectionBindingExpression = pbe2;\n                }\n\n                if (mappedProjectionBindingExpression == null)\n                {\n                    return QueryCompilationContext.NotTranslatedExpression;\n                }\n\n                var subquery = (SelectExpression)shapedQuery.QueryExpression;\n\n                var projection = mappedProjectionBindingExpression.ProjectionMember is { } projectionMember\n                    ? subquery.GetMappedProjection(projectionMember)\n                    : throw new NotImplementedException(\"Subquery with index projection binding\");\n                if (projection is not SqlExpression sqlExpression)\n                {\n                    return QueryCompilationContext.NotTranslatedExpression;\n                }\n\n                if (subquery.Sources.Count == 0)\n                {\n                    return sqlExpression;\n                }\n\n                // TODO TODO\n                // subquery.ReplaceProjection(new List<Expression> { sqlExpression });\n                subquery.ApplyProjection();\n\n                // Add VALUE to the subquery's projection (SELECT VALUE x ...), to make it project that value rather than a JSON object\n                // wrapping that value.\n                subquery = subquery.WithSingleValueProjection();\n","sourceCodeStart":437,"sourceCodeEnd":473,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Cosmos/Query/Internal/CosmosSqlTranslatingExpressionVisitor.cs#L437-L473","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Rewrite the query to flatten nested subqueries so the projection is member-based.","Insert AsEnumerable() (or ToListAsync()) before the subquery so it evaluates on the client.","Project scalar members directly inside the subquery instead of through a complex shaper.","File an issue on the dotnet/efcore repo with a minimal repro so the Cosmos team can implement the path."],"exampleFix":"// before\nvar q = await db.Users\n    .Where(u => u.Posts.Select(p => p.Title).Any(t => t.StartsWith(\"x\")))\n    .ToListAsync();\n\n// after - move the subquery predicate to the client\nvar users = await db.Users.ToListAsync();\nvar q = users\n    .Where(u => u.Posts.Select(p => p.Title).Any(t => t.StartsWith(\"x\")))\n    .ToList();","handlingStrategy":"fallback","validationCode":"// No public API to pre-check; detect unsupported subquery shapes by\n// wrapping exploratory queries in try/catch and falling back to AsEnumerable.\npublic static async Task<List<T>> SafeQuery<T>(IQueryable<T> query)\n{\n    try { return await query.ToListAsync(); }\n    catch (NotImplementedException) { return query.AsEnumerable().ToList(); }\n}","typeGuard":null,"tryCatchPattern":"try { result = await query.ToListAsync(); }\ncatch (NotImplementedException ex) when (ex.Message.Contains(\"Subquery\"))\n{ result = await query.AsAsyncEnumerable().ToListAsync(); }","preventionTips":["Prefer flat queries over nested subqueries when targeting Cosmos.","Unit-test query shapes against the Cosmos provider during development to catch unsupported translations early.","Keep subquery projections to primitive scalars rather than shaped objects."],"tags":["cosmos","query-translation","subquery","not-implemented"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}