dotnet/efcore · error · InvalidOperationException

ExecuteUpdateDeleteOnEntityNotMappedToTable

ExecuteUpdateDeleteOnEntityNotMappedToTable

Error message

'ExecuteUpdate' or 'ExecuteDelete' was called on entity type '{entityType}', but that entity type is not mapped to a table.

What it means

In ProcessColumn (line 438-502), when the table expression does not reference an ITable (e.g. it points at a view or a query-defining expression), EF looks up the corresponding mutable table column for the property. If no such column/table mapping exists (targetColumnModel is null at line 483), ExecuteUpdate/ExecuteDelete cannot target any table and throws ExecuteUpdateDeleteOnEntityNotMappedToTable.

Source

Thrown at src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteUpdate.cs:485

                            // See #28520 about improving this.
                            var containerColumnName = complexType.GetContainerColumnName();
                            if (containerColumnName != null)
                            {
                                targetColumnModel = complexType.GetTableMappings()
                                    .Select(m => m.Table.FindColumn(containerColumnName))
                                    .SingleOrDefault(c => c is not null);
                            }

                            break;
                        }

                        default:
                            throw new UnreachableException();
                    }

                    if (targetColumnModel is null)
                    {
                        throw new InvalidOperationException(
                            RelationalStrings.ExecuteUpdateDeleteOnEntityNotMappedToTable(targetProperty.DeclaringType.DisplayName()));
                    }

                    unwrappedTableExpression = new TableExpression(unwrappedTableExpression.Alias, targetColumnModel.Table);
                    tableExpression = tableExpression is JoinExpressionBase join
                        ? join.Update(unwrappedTableExpression)
                        : unwrappedTableExpression;
                    var newTables = select.Tables.ToList();
                    newTables[tableIndex] = tableExpression;

                    // Note that we need to keep the select mutable, because if IsValidSelectExpressionForExecuteDelete below
                    // returns false, we need to compose on top of it.
                    select.SetTables(newTables);
                }

                CheckColumnOnSameTable(column, propertySelector);
            }

View on GitHub (pinned to dbf9771522)

Solutions

  1. Map the entity to a real table with ToTable so it has a mutable table mapping.
  2. If the entity is genuinely a view, perform the update against the underlying base table entity or via raw SQL.
  3. Remove ToView and let EF map by convention to a table, or add an explicit ToTable.

Example fix

// before (entity mapped only to a view)
modelBuilder.Entity<OrderView>().ToView("OrderView").HasNoKey();
db.Set<OrderView>().Where(o => o.Stale)
    .ExecuteDelete();

// after (map to a real table so a mutation target exists)
modelBuilder.Entity<OrderView>().ToTable("OrderView");
db.Set<OrderView>().Where(o => o.Stale)
    .ExecuteDelete();
Defensive patterns

Strategy: validation

Validate before calling

// Verify the entity has a table mapping (not only a view) before mutating.
foreach (var t in entityType.GetTableMappings()) { /* ok: has a table */ return; }
throw new InvalidOperationException("Entity is not mapped to a table; ExecuteUpdate/ExecuteDelete will fail.");

Try / catch

try { await q.ExecuteDeleteAsync(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("not mapped to a table"))
{ /* add ToTable mapping, or target the base table entity / raw SQL */ }

Prevention

When it happens

Trigger: Calling ExecuteUpdate or ExecuteDelete on an entity type that is mapped only to a view (ToView, no ToTable), to a function, or to a query (HasNoKey + defining query), so GetTableMappings yields no ITable and no mutable column can be found.

Common situations: Read-only view entities mistakenly used for bulk updates; entities configured with ToView instead of ToTable; defining queries (ToQuery) entities; database-first scaffolding that produced view-only mappings.

Related errors


AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06). Data as JSON: /api/errors/b087417c4389fa36. Report an issue: GitHub.