{"record":{"id":"1d6c332af472d48a","repo":"dotnet/efcore","slug":"unable-to-translate-set-operation-after-client-pro","errorCode":null,"errorMessage":"Unable to translate set operation after client projection has been applied. Consider moving the set operation before the last 'Select' call.","messagePattern":"Unable to translate set operation after client projection has been applied\\. Consider moving the set operation before the last 'Select' call\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.InMemory/Query/Internal/InMemoryQueryExpression.cs","lineNumber":446,"sourceCode":"                        NewArrayInit(\n                            typeof(object),\n                            source1SelectorExpressions.Select(e => e.Type.IsValueType ? Convert(e, typeof(object)) : e))),\n                    CurrentParameter));\n\n            source2.ServerQueryExpression = Call(\n                EnumerableMethods.Select.MakeGenericMethod(source2.ServerQueryExpression.Type.GetSequenceType(), typeof(ValueBuffer)),\n                source2.ServerQueryExpression,\n                Lambda(\n                    New(\n                        ValueBufferConstructor,\n                        NewArrayInit(\n                            typeof(object),\n                            source2SelectorExpressions.Select(e => e.Type.IsValueType ? Convert(e, typeof(object)) : e))),\n                    source2.CurrentParameter));\n        }\n        else\n        {\n            throw new InvalidOperationException(InMemoryStrings.SetOperationsNotAllowedAfterClientEvaluation);\n        }\n\n        ServerQueryExpression = Call(\n            setOperationMethodInfo.MakeGenericMethod(typeof(ValueBuffer)), ServerQueryExpression, source2.ServerQueryExpression);\n    }\n\n    /// <summary>\n    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to\n    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in\n    ///     any release. You should only use it directly in your code with extreme caution and knowing that\n    ///     doing so can result in application failures when updating to a new Entity Framework Core release.\n    /// </summary>\n    public virtual void ApplyDefaultIfEmpty()\n    {\n        if (_clientProjections.Count != 0)\n        {\n            throw new InvalidOperationException(InMemoryStrings.DefaultIfEmptyAppliedAfterProjection);\n        }","sourceCodeStart":428,"sourceCodeEnd":464,"githubUrl":"https://github.com/dotnet/efcore/blob/dbf9771522148d61a2467854921bd5dc6f6e6916/src/EFCore.InMemory/Query/Internal/InMemoryQueryExpression.cs#L428-L464","documentation":"ApplySetOperation (Union/Concat/Intersect/Except) checks _clientProjections.Count and throws if a client-evaluated projection has already been applied (InMemoryQueryExpression.cs:444-446). The InMemory provider can only combine two queries in pure server-evaluation form; once the projection becomes client-side, set operations are not supported.","triggerScenarios":"Calling a set operation (Union/Concat/Intersect/Except) AFTER a Select that triggered client evaluation, e.g. db.Set<A>().Select(a => clientSideExpr).Concat(db.Set<B>().Select(...)).","commonSituations":"Combining two queries with Union/Concat where each side has a projection containing client-side computation, or projecting a DTO then unioning. Common when porting SQL UNION-style queries to LINQ.","solutions":["Move the set operation BEFORE the last Select call so both operands are still server-evaluated.","Insert AsEnumerable() before the set operation to perform it client-side.","Remove client-evaluated expressions from the Select preceding the set operation."],"exampleFix":"// before\nvar q = db.Users.Select(u => new { u.Id, Name = u.First + \" \" + u.Last })\n             .Union(db.Admins.Select(a => new { a.Id, Name = a.First + \" \" + a.Last }));\n// after\nvar q = db.Users.Union(db.Admins)\n             .Select(x => new { x.Id, Name = x.First + \" \" + x.Last });","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try\n{\n    var r = q1.Select(proj).Concat(q2.Select(proj)).ToList();\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"set operation after client projection\"))\n{\n    var r = q1.AsEnumerable().Select(proj)\n              .Concat(q2.AsEnumerable().Select(proj)).ToList();\n}","preventionTips":["Place Union/Concat/Intersect/Except BEFORE any Select that triggers client evaluation.","When combining two sources, project after the set operation, not before.","Use AsEnumerable() before the set operation to perform it client-side when needed."],"tags":["ef-core","in-memory-provider","linq-translation","set-operation","union"],"analyzedSha":"dbf9771522148d61a2467854921bd5dc6f6e6916","analyzedAt":"2026-08-06T20:46:03.226Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}