{"record":{"id":"1b351a41698f1ad1","repo":"dotnet/efcore","slug":"executedeleteontablesplitting","errorCode":"ExecuteDeleteOnTableSplitting","errorMessage":"The operation 'ExecuteDelete' is being applied on the table '{tableName}' which contains data for multiple entity types. Applying this delete operation will also delete data for other entity type(s), hence it is not supported.","messagePattern":"The operation 'ExecuteDelete' is being applied on the table '(.+?)' which contains data for multiple entity types\\. Applying this delete operation will also delete data for other entity type\\(s\\), hence it is not supported\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteDelete.cs","lineNumber":100,"sourceCode":"                tableExpression = tableExpression is JoinExpressionBase join\n                    ? join.Update(unwrappedTableExpression)\n                    : unwrappedTableExpression;\n                var newTables = selectExpression.Tables.ToList();\n                newTables[tableIndex] = tableExpression;\n\n                // Note that we need to keep the select mutable, because if IsValidSelectExpressionForExecuteDelete below returns false,\n                // we need to compose on top of it.\n                selectExpression.SetTables(newTables);\n            }\n\n            // Finally, check if the provider has a native translation for the delete represented by the select expression.\n            // The default relational implementation handles simple, universally-supported cases (i.e. no operators except for predicate).\n            // Providers may override IsValidSelectExpressionForExecuteDelete to add support for more cases via provider-specific DELETE syntax.\n            if (IsValidSelectExpressionForExecuteDelete(selectExpression))\n            {\n                if (AreOtherNonOwnedEntityTypesInTheTable(entityType.GetRootType(), targetTable))\n                {\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(","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/dotnet/efcore/blob/dbf9771522148d61a2467854921bd5dc6f6e6916/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteDelete.cs#L82-L118","documentation":"Thrown by TranslateExecuteDelete when the target table is shared by multiple entity types (table splitting / shared tables, e.g. an owned entity sharing its principal's table, or two entities mapped to the same table) and deleting would affect rows belonging to other entity types. EF refuses to issue a delete that could corrupt data for the co-located types.","triggerScenarios":"Calling ExecuteDelete on an entity whose table is also mapped (non-owned, different root) to another entity type; or table sharing where the principal and a non-owned dependent share the same table.","commonSituations":"Table splitting scenarios (multiple entities mapped to one physical table); joining two entity types to the same table for read convenience; owned entities whose owner shares the table with another principal.","solutions":["Map only one entity type per table, or ensure shared tables only contain owned dependents (owned types are excluded from this check).","Load entities and delete via SaveChanges, which orders operations to respect shared-table invariants.","Use raw SQL (Database.ExecuteSqlRaw) only if you can guarantee no cross-type row corruption.","Restructure so the deletable entity has its own dedicated table."],"exampleFix":"// before - Customer and CustomerAudit share the Customers table\nmodelBuilder.Entity<Customer>().ToTable(\"Customers\");\nmodelBuilder.Entity<CustomerAudit>().ToTable(\"Customers\");\nawait db.Customers.Where(c => c.Id == id).ExecuteDeleteAsync();\n// after - give each entity its own table\nmodelBuilder.Entity<CustomerAudit>().ToTable(\"CustomerAudits\");\nawait db.Customers.Where(c => c.Id == id).ExecuteDeleteAsync();","handlingStrategy":"validation","validationCode":"static bool TableHasOtherNonOwnedRoots(IEntityType et)\n{\n    foreach (var tm in et.GetTableMappings())\n        foreach (var m in tm.Table.EntityTypeMappings)\n            if (m.TypeBase is IEntityType other && other.GetRootType() != et.GetRootType() && !other.IsOwned())\n                return true;\n    return false;\n}\n\nif (TableHasOtherNonOwnedRoots(entityType))\n    throw new InvalidOperationException(\"ExecuteDelete would affect other entity types sharing the table.\");","typeGuard":null,"tryCatchPattern":"try { await db.Customers.Where(c => c.Id == id).ExecuteDeleteAsync(); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"multiple entity types\"))\n{\n    var c = await db.Customers.FindAsync(id);\n    db.Customers.Remove(c);\n    await db.SaveChangesAsync();\n}","preventionTips":["Map only one (non-owned) entity type per physical table when bulk-deleting.","Use owned types for shared-table dependents (they are excluded from this check).","Use SaveChanges for shared-table deletes, which respect invariants.","Audit the relational model for unintended table sharing."],"tags":["executedelete","table-splitting","shared-tables","bulk-operations"],"analyzedSha":"dbf9771522148d61a2467854921bd5dc6f6e6916","analyzedAt":"2026-08-06T20:46:03.226Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}