{"record":{"id":"3662e9fddd4881a1","repo":"dotnet/efcore","slug":"cannot-translate-comparisonoperator-on-a-subqu-3662e9","errorCode":null,"errorMessage":"Cannot translate '{comparisonOperator}' on a subquery expression of entity type '{entityType}' because it has a composite primary key. See https://go.microsoft.com/fwlink/?linkid=2141942 for information on how to rewrite your query.","messagePattern":"Cannot translate '(.+?)' on a subquery expression of entity type '(.+?)' because it has a composite primary key\\. See https://go\\.microsoft\\.com/fwlink/\\?linkid=2141942 for information on how to rewrite your query\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.InMemory/Query/Internal/InMemoryExpressionTranslatingExpressionVisitor.cs","lineNumber":1275,"sourceCode":"    {\n        result = null;\n\n        if (item is not StructuralTypeReferenceExpression { StructuralType: IEntityType entityType })\n        {\n            return false;\n        }\n\n        var primaryKeyProperties = entityType.FindPrimaryKey()?.Properties;\n        if (primaryKeyProperties == null)\n        {\n            throw new InvalidOperationException(\n                CoreStrings.EntityEqualityOnKeylessEntityNotSupported(\n                    nameof(Queryable.Contains), entityType.DisplayName()));\n        }\n\n        if (primaryKeyProperties.Count > 1)\n        {\n            throw new InvalidOperationException(\n                CoreStrings.EntityEqualityOnCompositeKeyEntitySubqueryNotSupported(\n                    nameof(Queryable.Contains), entityType.DisplayName()));\n        }\n\n        var property = primaryKeyProperties[0];\n        Expression rewrittenSource;\n        switch (source)\n        {\n            case ConstantExpression constantExpression:\n                var values = constantExpression.GetConstantValue<IEnumerable>();\n                var propertyValueList =\n                    (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(property.ClrType.MakeNullable()))!;\n                var propertyGetter = property.GetGetter();\n                foreach (var value in values)\n                {\n                    propertyValueList.Add(propertyGetter.GetClrValue(value));\n                }\n","sourceCodeStart":1257,"sourceCodeEnd":1293,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.InMemory/Query/Internal/InMemoryExpressionTranslatingExpressionVisitor.cs#L1257-L1293","documentation":"Thrown from TryRewriteContainsEntity when Contains is applied to a subquery whose entity type has a composite primary key (more than one key property). The InMemory translator can only rewrite Contains over single-key entities; composite-key entity subqueries have no single column to expand into an IN list.","triggerScenarios":"Queryable.Contains over a subquery (e.g. db.Orders.Contains(order) where db.Orders is itself a subquery, or the source is a ConstantExpression of entities) and the entity's FindPrimaryKey().Properties.Count > 1.","commonSituations":"Entities with composite keys (junction tables, many-to-many join entities) used inside a Contains against a subquery. Refactoring equality checks to use Contains when moving to composite keys.","solutions":["Rewrite Contains on a composite-key entity as a JOIN on all key columns, or as multiple paired Where conditions.","Materialize the subquery with AsEnumerable() and perform the Contains client-side.","Project to a tuple/string key and Contains on that single value: db.Orders.Select(o => new { o.A, o.B }).AsEnumerable().Contains(...).","Avoid Contains over composite-key subqueries; prefer Any(x => x.A == a && x.B == b)."],"exampleFix":"// before\ndb.Joins.Contains(joinEntity);\n// after\ndb.Joins.Any(j => j.A == joinEntity.A && j.B == joinEntity.B);","handlingStrategy":"validation","validationCode":"var pk = dbContext.Model.FindEntityType(typeof(Join))?.FindPrimaryKey();\nif (pk is { Properties.Count: > 1 })\n    throw new InvalidOperationException(\"Composite-key entity: use Any(...) instead of Contains over a subquery\");","typeGuard":"static bool HasCompositeKey(IEntityType et)\n    => et.FindPrimaryKey()?.Properties.Count > 1;","tryCatchPattern":"try { return db.Joins.Contains(item); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"composite primary key\"))\n{\n    return db.Joins.Any(j => j.A == item.A && j.B == item.B);\n}","preventionTips":["Avoid Contains over composite-key entity subqueries; use Any on all key columns.","Project to a single string/tuple key for membership checks.","Materialize with AsEnumerable() if Contains is unavoidable."],"tags":["in-memory","query","translation","composite-key","entity-equality"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}