{"record":{"id":"38ed33c1b342b624","repo":"dotnet/efcore","slug":"the-operation-operation-cannot-be-performed-on","errorCode":null,"errorMessage":"The operation '{operation}' cannot be performed on keyless entity type '{entityType}', since it contains an operator not natively supported by the database provider.","messagePattern":"The operation '(.+?)' cannot be performed on keyless entity type '(.+?)', since it contains an operator not natively supported by the database provider\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteDelete.cs","lineNumber":117,"sourceCode":"                {\n                    throw new InvalidOperationException(\n                        RelationalStrings.ExecuteDeleteOnTableSplitting(unwrappedTableExpression.Table.SchemaQualifiedName));\n                }\n\n                selectExpression.ReplaceProjection([]);\n                selectExpression.ApplyProjection();\n\n                return new DeleteExpression(unwrappedTableExpression, selectExpression);\n            }\n        }\n\n        // We can't translate to a simple delete (e.g. the provider doesn't support one of the clauses).\n        // As a fallback, we place the original query in a Contains subquery, which will get translated via the regular entity equality/\n        // containment mechanism (InExpression for non-composite keys, Any for composite keys)\n        var pk = entityType.FindPrimaryKey();\n        if (pk == null)\n        {\n            throw new InvalidOperationException(\n                RelationalStrings.ExecuteOperationOnKeylessEntityTypeWithUnsupportedOperator(\n                    nameof(EntityFrameworkQueryableExtensions.ExecuteDelete),\n                    entityType.DisplayName()));\n        }\n\n        var clrType = entityType.ClrType;\n        var entityParameter = Expression.Parameter(clrType);\n        var predicateBody = Expression.Call(QueryableMethods.Contains.MakeGenericMethod(clrType), source, entityParameter);\n\n        var newSource = Expression.Call(\n            QueryableMethods.Where.MakeGenericMethod(clrType),\n            new EntityQueryRootExpression(entityType),\n            Expression.Quote(Expression.Lambda(predicateBody, entityParameter)));\n\n        return TranslateExecuteDelete((ShapedQueryExpression)Visit(newSource));\n\n        static bool AreOtherNonOwnedEntityTypesInTheTable(IEntityType rootType, ITableBase table)\n        {","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteDelete.cs#L99-L135","documentation":"When the query cannot be turned into a native single-table DELETE, EF falls back to a Contains/Any subquery over the primary key. This fallback requires a primary key; the throw fires when entityType.FindPrimaryKey() is null (keyless entity) and the query contained an operator the provider does not natively support in a DELETE. Keyless entities have no key to build the subquery with, so neither path works.","triggerScenarios":"context.Set<KeylessView>().Where(...).OrderBy(...).Take(...).ExecuteDelete() (or any unsupported operator beyond a simple predicate) where KeylessView is mapped HasNoKey. The native DELETE path fails on the unsupported operator, and the subquery fallback fails on the missing key.","commonSituations":"Database views mapped as keyless entities; query-only types; missing key configuration on what was intended to be an updatable table.","solutions":["Define a primary key on the entity (remove HasNoKey / configure a key) so the subquery fallback works.","Simplify the query so it falls inside the provider's natively-supported DELETE shape (single table + WHERE predicate only).","Issue the delete via raw SQL against the underlying table."],"exampleFix":"// before (keyless + unsupported operator -> 597)\nmodelBuilder.Entity<ThingView>().HasNoKey().ToView(\"v_things\");\nawait db.Set<ThingView>().OrderBy(t => t.Id).Take(100).ExecuteDeleteAsync();\n// after (simplify to supported predicate)\nawait db.Set<ThingView>().Where(t => t.Old).ExecuteDeleteAsync();\n// or give the entity a key and a table mapping","handlingStrategy":"validation","validationCode":"// For keyless entities, restrict ExecuteDelete to a simple predicate the provider renders natively.\nvar et = db.Model.FindEntityType(typeof(TEntity))!;\nif (et.FindPrimaryKey() is null)\n{\n    Console.WriteLine($\"{et.Name} is keyless; keep ExecuteDelete sources to a simple Where predicate, \"\n                      + \"or define a key, or use raw SQL.\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Give entities a primary key whenever they back bulk operations.","Keep ExecuteDelete sources for keyless types to single-table WHERE predicates only.","Fall back to raw SQL when complex operators are unavoidable on keyless types."],"tags":["efcore","executedelete","keyless","query-translation"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}