{"record":{"id":"d239dda6d6e6df8b","repo":"dotnet/efcore","slug":"using-distinct-operation-on-a-projection-contain","errorCode":null,"errorMessage":"Using 'Distinct' operation on a projection containing a subquery is not supported.","messagePattern":"Using 'Distinct' operation on a projection containing a subquery is not supported\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.InMemory/Query/Internal/InMemoryQueryExpression.cs","lineNumber":515,"sourceCode":"\n        var selectorExpressions = new List<Expression>();\n        if (_clientProjections.Count == 0)\n        {\n            selectorExpressions.AddRange(_projectionMappingExpressions);\n            if (selectorExpressions.Count == 0)\n            {\n                // No server correlated term in projection so add dummy 1.\n                selectorExpressions.Add(Constant(1));\n            }\n        }\n        else\n        {\n            for (var i = 0; i < _clientProjections.Count; i++)\n            {\n                var projection = _clientProjections[i];\n                if (projection is InMemoryQueryExpression)\n                {\n                    throw new InvalidOperationException(InMemoryStrings.DistinctOnSubqueryNotSupported);\n                }\n\n                if (projection is EntityProjectionExpression entityProjectionExpression)\n                {\n                    _clientProjections[i] = TraverseEntityProjection(\n                        selectorExpressions, entityProjectionExpression, makeNullable: false);\n                }\n                else\n                {\n                    selectorExpressions.Add(projection);\n                    _clientProjections[i] = CreateReadValueExpression(\n                        projection.Type, selectorExpressions.Count - 1, InferPropertyFromInner(projection));\n                }\n            }\n        }\n\n        var selectorLambda = Lambda(\n            New(","sourceCodeStart":497,"sourceCodeEnd":533,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.InMemory/Query/Internal/InMemoryQueryExpression.cs#L497-L533","documentation":"When the InMemory provider applies Distinct (ApplyDistinct), it walks every accumulated client projection slot. If any slot is itself an InMemoryQueryExpression (i.e. a nested subquery), the provider cannot deduplicate because the subquery result is not a scalar value it can compare at the ValueBuffer level. It throws DistinctOnSubqueryNotSupported from the loop that processes _clientProjections.","triggerScenarios":"Calling Distinct() on a query whose projection includes a collection navigation or subquery that has been accumulated as a client projection. The throw occurs during ApplyDistinct when iterating over client projection slots.","commonSituations":"Projecting a collection navigation (e.g. .Select(b => new { b.Title, b.Posts })) and then calling .Distinct(), or using a correlated subquery inside a Select followed by Distinct. Common when trying to deduplicate parent rows after eagerly loading children.","solutions":["Remove the subquery/collection from the projection before calling Distinct, then re-attach it after materialization.","Call AsEnumerable() before Distinct to perform deduplication client-side on the materialized objects.","Use GroupBy or SelectMany to flatten the data so Distinct operates on scalar values only."],"exampleFix":"// before — Distinct on a projection containing a subquery\nvar result = ctx.Blogs\n    .Select(b => new { b.Title, PostCount = b.Posts.Count() })\n    .Distinct();\n\n// after — materialize then Distinct client-side\nvar result = ctx.Blogs\n    .Select(b => new { b.Title, PostCount = b.Posts.Count() })\n    .AsEnumerable()\n    .Distinct();","handlingStrategy":"validation","validationCode":"// Validate: do not call Distinct() on a projection that includes a subquery\n// or collection navigation. Project scalar values only before Distinct.\n// If the projection must include subqueries, call AsEnumerable() first.\nvar distinctTitles = ctx.Blogs.Select(b => b.Title).Distinct(); // safe — scalar only","typeGuard":null,"tryCatchPattern":"try\n{\n    return query.Distinct().ToList();\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"Distinct\"))\n{\n    // Materialize first, then apply Distinct client-side\n    return query.AsEnumerable().Distinct().ToList();\n}","preventionTips":["Project only scalar values before calling Distinct.","Remove collection navigations and subqueries from the Select before Distinct.","Use AsEnumerable() before Distinct when the projection must include subqueries.","Consider GroupBy on a key property instead of Distinct on complex projections."],"tags":["efcore","inmemory","query-translation","distinct","subquery"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}