dotnet/efcore · error · InvalidOperationException
MultipleTablesInExecuteUpdate
MultipleTablesInExecuteUpdate
Error message
Multiple 'SetProperty' invocations refer to different tables ('{propertySelector1}' and '{propertySelector2}'). A single 'ExecuteUpdate' call can only update the columns of a single table. What it means
CheckColumnOnSameTable (line 772-784) records the table alias of the first setter's column and verifies every subsequent setter's column lives on the same table. A single UPDATE statement can only target one table, so if two SetProperty calls resolve to columns on different tables, MultipleTablesInExecuteUpdate is thrown, naming both offending selectors.
Source
Thrown at src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteUpdate.cs:781
}
var result = _sqlTranslator.TranslateProjection(remappedValueSelector, applyDefaultTypeMapping: false);
return result is null
? throw new InvalidOperationException(RelationalStrings.InvalidValueInSetProperty(valueSelector.Print()))
: result;
}
void CheckColumnOnSameTable(ColumnExpression column, LambdaExpression propertySelector)
{
if (targetTableAlias is null)
{
targetTableAlias = column.TableAlias;
targetTablePropertySelector = propertySelector;
}
else if (column.TableAlias != targetTableAlias)
{
throw new InvalidOperationException(
RelationalStrings.MultipleTablesInExecuteUpdate(propertySelector.Print(), targetTablePropertySelector!.Print()));
}
}
// If the entire JSON column is being referenced, remove the JsonQueryExpression altogether and just return
// the column (no need for special JSON modification functions/syntax).
// See #30768 for stopping producing empty Json{Scalar,Query}Expressions.
// Otherwise, convert the JsonQueryExpression to a JsonScalarExpression, which is our current representation for a complex
// JSON in the SQL tree (as opposed to in the shaper) - see #36392.
static SqlExpression ProcessJsonQuery(JsonQueryExpression jsonQuery)
=> jsonQuery.Path is []
? jsonQuery.JsonColumn
: new JsonScalarExpression(
jsonQuery.JsonColumn,
jsonQuery.Path,
jsonQuery.Type,
jsonQuery.JsonColumn.TypeMapping,
jsonQuery.IsNullable);View on GitHub (pinned to dbf9771522)
Solutions
- Restrict a single ExecuteUpdate to properties of one table; issue separate ExecuteUpdate calls per table.
- Map the dependent/owned entity to the same table (table splitting) so all columns share one alias.
- Reorder so each ExecuteUpdate call's setters are all on the principal table.
Example fix
// before (User and Profile live on different tables)
db.Users.ExecuteUpdate(s => s
.SetProperty(u => u.Name, "x")
.SetProperty(u => u.Profile.Bio, "y"));
// after (one ExecuteUpdate per table)
db.Users.ExecuteUpdate(s => s.SetProperty(u => u.Name, "x"));
db.Profiles.ExecuteUpdate(s => s.SetProperty(p => p.Bio, "y")); Defensive patterns
Strategy: validation
Validate before calling
// Verify all setter target properties map to the same table before calling ExecuteUpdate.
var tables = setters.Select(s => GetTableFor(s.Property)).Distinct();
if (tables.Count() > 1) throw new InvalidOperationException("Setters target multiple tables; split into separate ExecuteUpdate calls."); Try / catch
try { await q.ExecuteUpdateAsync(s => s.SetProperty(e => e.A, 1).SetProperty(e => e.Nav.B, 2)); }
catch (InvalidOperationException ex) when (ex.Message.Contains("different tables"))
{ /* issue one ExecuteUpdate per table */ } Prevention
- Keep each ExecuteUpdate scoped to one table's columns.
- Use table splitting (ToTable same name) for owned entities updated together.
- Split multi-table updates into sequential ExecuteUpdate calls.
When it happens
Trigger: Chaining SetProperty calls whose properties map to columns on different tables: e.g. SetProperty(e => e.Name, ...).SetProperty(e => e.Profile.Bio, ...) where Profile is a table-split or owned entity on a separate table, or two entities sharing a table via splitting where EF chose different tables.
Common situations: Table splitting where the dependent lives on a different table; owned entities mapped to their own tables; TPT/TPC inheritance where properties map to different hierarchy tables; attempting a multi-table update in one ExecuteUpdate call.
Related errors
- ExecuteOperationOnKeylessEntityTypeWithUnsupportedOperator
- ExecuteOperationOnOwnedJsonIsNotSupported
- ExecuteUpdateOverJsonIsNotSupported
- ExecuteUpdateCannotSetJsonPropertyToNonJsonColumn
- ExecuteUpdateCannotSetJsonPropertyToArbitraryExpression
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/2e3fcb2ead9a282f.
Report an issue: GitHub.