dotnet/efcore · error · InvalidOperationException
The operation '{operation}' is being applied on entity type
Error message
The operation '{operation}' is being applied on entity type '{entityType}', which is using the TPT mapping strategy. 'ExecuteDelete'/'ExecuteUpdate' operations on hierarchies mapped as TPT are not supported. What it means
TranslateExecuteDelete switches on GetMappingStrategy() and throws for TPT (table-per-type). In TPT each type has its own table, so a single parametrized DELETE statement cannot correctly remove a hierarchy's rows across multiple tables; EF therefore refuses ExecuteDelete/ExecuteUpdate on TPT hierarchies.
Source
Thrown at src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteDelete.cs:29
protected override DeleteExpression TranslateExecuteDelete(ShapedQueryExpression source)
{
source = source.UpdateShaperExpression(new IncludePruner().Visit(source.ShaperExpression));
if (source.ShaperExpression is not StructuralTypeShaperExpression { StructuralType: IEntityType entityType } shaper)
{
throw new InvalidOperationException(RelationalStrings.ExecuteDeleteOnNonEntityType);
}
if (entityType.IsMappedToJson())
{
throw new InvalidOperationException(
RelationalStrings.ExecuteOperationOnOwnedJsonIsNotSupported("ExecuteDelete", entityType.DisplayName()));
}
switch (entityType.GetMappingStrategy())
{
case RelationalAnnotationNames.TptMappingStrategy:
throw new InvalidOperationException(
RelationalStrings.ExecuteOperationOnTPT(
nameof(EntityFrameworkQueryableExtensions.ExecuteDelete),
entityType.DisplayName()));
// Note that we do allow TPC if the target is a leaf type
case RelationalAnnotationNames.TpcMappingStrategy when entityType.GetDirectlyDerivedTypes().Any():
throw new InvalidOperationException(
RelationalStrings.ExecuteOperationOnTPC(
nameof(EntityFrameworkQueryableExtensions.ExecuteDelete),
entityType.DisplayName()));
}
// Find the table model that maps to the entity type; there must be exactly one (e.g. no entity splitting).
var targetTable = entityType.GetTableMappings().ToList() switch
{
[] => throw new InvalidOperationException(
RelationalStrings.ExecuteUpdateDeleteOnEntityNotMappedToTable(entityType.DisplayName())),
[var singleTableMapping] => singleTableMapping.Table,View on GitHub (pinned to 3a2006ef56)
Solutions
- Switch the hierarchy to TPH (single table) or TPC if bulk delete/update is required.
- Issue per-table raw SQL deletes (base + each subtype) in the correct order via Database.ExecuteSqlRaw.
- Load entities and use RemoveRange + SaveChanges, which correctly deletes across TPT tables.
- Target a specific concrete leaf type with its own mapping that is not TPT.
Example fix
// before (TPT hierarchy)
await db.Set<TptBase>().Where(b => b.Stale).ExecuteDeleteAsync();
// after (per-table raw SQL or SaveChanges)
foreach (var id in ids) { var e = await db.Set<TptBase>().FindAsync(id); if (e != null) db.Remove(e); }
await db.SaveChangesAsync(); Defensive patterns
Strategy: validation
Validate before calling
// Reject ExecuteDelete/ExecuteUpdate on TPT hierarchies before calling.
var et = db.Model.FindEntityType(typeof(TEntity))!;
var strategy = et.GetMappingStrategy();
if (strategy == RelationalAnnotationNames.TptMappingStrategy)
throw new InvalidOperationException(
"ExecuteDelete/ExecuteUpdate is not supported on TPT hierarchies; use TPH/TPC or SaveChanges/raw SQL."); Prevention
- Pick TPH or TPC if bulk delete/update is a common operation in the hierarchy.
- Use SaveChanges or raw per-table SQL when TPT is mandatory.
- Document mapping-strategy constraints for bulk operations in the team's data-access guidelines.
When it happens
Trigger: context.Set<TptBase>().ExecuteDelete() (or on a derived type) where the hierarchy is mapped with .UseTptMappingStrategy(); similarly ExecuteUpdate on the same. Triggered as soon as the target entity type's mapping strategy resolves to TPT.
Common situations: Existing TPT hierarchies where a developer expects bulk delete to work; switching a hierarchy from TPH to TPT and re-running a previously-working ExecuteDelete.
Related errors
- The operation '{operation}' is being applied on entity type
- The element type of the result of '{dbFunction}' is mapped t
- The mapping strategy '{mappingStrategy}' specified on '{enti
- The mapping strategy '{mappingStrategy}' used for '{entityTy
- The specified discriminator value '{value}' for '{entityType
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/47cf4a945dd3342c.
Report an issue: GitHub.