{"record":{"id":"48a387676a65bb85","repo":"dotnet/efcore","slug":"complex-projections-in-subqueries-are-currently-un","errorCode":null,"errorMessage":"Complex projections in subqueries are currently unsupported.","messagePattern":"Complex projections in subqueries are currently unsupported\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Cosmos/Query/Internal/Expressions/SelectExpression.cs","lineNumber":599,"sourceCode":"                {\n                    SqlExpression e => new ScalarReferenceExpression(joinSource.Alias, e.Type, e.TypeMapping),\n                    StructuralTypeProjectionExpression e => e.Update(new ObjectReferenceExpression(e.StructuralType, joinSource.Alias)),\n\n                    _ => throw new UnreachableException(\n                        $\"Unexpected expression type in projection when adding join: {expression.GetType().Name}\")\n                };\n            }\n            else\n            {\n                // TODO: #34004\n                // The subquery is projecting out a JSON object; for the projection mapping of the outer query, we need to generate\n                // property accesses over that object: Scalar/ObjectAccessExpressions over the ObjectReferenceExpression that references\n                // the JOIN source.\n                // However, the JSON object being projected out of the subquery doesn't correspond to any entity type, and there's currently\n                // no way for us to represent a reference to that - ObjectReferenceExpression requires an IEntityType. Changing that\n                // requires shaper-side changes (see comment in ObjectReferenceExpression); if we can remove that requirement, we can\n                // possibly also merge ScalarReferenceExpression and ObjectReferenceExpression to a single SourceReferenceExpression.\n                throw new InvalidOperationException(CosmosStrings.ComplexProjectionInSubqueryNotSupported);\n            }\n\n            projectionMapping[remappedProjectionMember] = projectionToAdd;\n        }\n\n        innerSelect.ApplyProjection();\n        _sources.Add(joinSource);\n\n        innerShaper = new ProjectionMemberRemappingExpressionVisitor(this, mapping).Visit(innerShaper);\n        _projectionMapping = projectionMapping;\n        innerSelect._projectionMapping.Clear();\n\n        return New(\n            transparentIdentifierType.GetTypeInfo().DeclaredConstructors.Single(),\n            [outerShaper, innerShaper], outerMemberInfo, innerMemberInfo);\n    }\n\n    /// <summary>","sourceCodeStart":581,"sourceCodeEnd":617,"githubUrl":"https://github.com/dotnet/efcore/blob/dbf9771522148d61a2467854921bd5dc6f6e6916/src/EFCore.Cosmos/Query/Internal/Expressions/SelectExpression.cs#L581-L617","documentation":"When SelectExpression.AddJoin folds a subquery into a JOIN, it must map the inner query's projection into the outer projection. For scalar inner projections this works, but when an inner projection emits a JSON object (complex/owned value or anonymous object) there is no way to reference that object across the JOIN (tracked as TODO #34004), so it throws InvalidOperationException.","triggerScenarios":"A LINQ query whose join/select-many inner source projects a complex or owned object (non-scalar) rather than scalar fields — e.g. joining and then projecting whole embedded entities from the inner side.","commonSituations":"Complex projections inside joins; projecting owned types out of a joined subquery; advanced SelectMany shapes ported from relational providers.","solutions":["Project scalar properties out of the inner subquery instead of whole objects (e.g. Select(x => x.Name) rather than selecting the entity).","Restructure the query to avoid the join (fetch roots then load related data separately).","Materialize the relevant entities client-side with separate queries and stitch them in memory."],"exampleFix":"// before\nvar q = from o in ctx.Orders\n        from c in ctx.Customers.Where(c => c.Id == o.CustomerId).Select(c => c.Address)\n        select new { o, c };\n\n// after: project scalars from the inner subquery\nvar q = from o in ctx.Orders\n        from c in ctx.Customers.Where(c => c.Id == o.CustomerId)\n        select new { o.Id, City = c.Address.City };","handlingStrategy":"validation","validationCode":"// Project scalars from the inner side of joins to avoid complex subquery projections.\nstatic IQueryable<TResult> JoinScalar<TOuter, TInner, TKey, TResult>(\n    IQueryable<TOuter> outer, IQueryable<TInner> inner,\n    Expression<Func<TOuter, TKey>> ok, Expression<Func<TInner, TKey>> ik,\n    Expression<Func<TOuter, TInner, TResult>> sel)\n    where TResult : class // ensure TResult is built from scalars, not whole objects\n    => outer.Join(inner, ok, ik, sel);","typeGuard":null,"tryCatchPattern":"try { var q = query.ToList(); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"Complex projections in subqueries\"))\n{ /* project scalars or load client-side */ }","preventionTips":["Project scalar fields from inner subqueries, not whole entities.","Prefer separate queries stitched client-side for complex join shapes."],"tags":["cosmos","subquery","join","projection","unsupported"],"analyzedSha":"dbf9771522148d61a2467854921bd5dc6f6e6916","analyzedAt":"2026-08-06T20:46:03.226Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}