dotnet/efcore · error · InvalidOperationException
Multiple 'SetProperty' invocations refer to different tables
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
Thrown by CheckColumnOnSameTable when two SetProperty calls within one ExecuteUpdate resolve to columns on different tables. A single ExecuteUpdate can only modify columns of one table; mixing tables (e.g. via TPT inheritance or navigations) is rejected.
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 3a2006ef56)
Solutions
- Split into multiple ExecuteUpdate calls, one per table.
- For TPT, ensure both properties belong to the same table or restructure to TPH if single-call updates are required.
- Drop the SetProperty that targets a different table (often a navigation) from the combined call.
Example fix
// before
await ctx.Set<Order>()
.ExecuteUpdateAsync(s => s
.SetProperty(o => o.OrderDate, DateTime.Now)
.SetProperty(o => o.Customer.ContactName, "x"));
// after
await ctx.Set<Order>()
.ExecuteUpdateAsync(s => s.SetProperty(o => o.OrderDate, DateTime.Now));
await ctx.Set<Customer>()
.Where(c => c.Orders.Any())
.ExecuteUpdateAsync(s => s.SetProperty(c => c.ContactName, "x")); Defensive patterns
Strategy: validation
Validate before calling
// Group setters by table before issuing ExecuteUpdate. // Static analysis: ensure both properties map to the same table. IEntityType et = ctx.Model.FindEntityType(typeof(Order))!; var p1 = et.FindProperty(nameof(Order.OrderDate))!; // Customer.ContactName lives on a different entity/table -> split the call.
Prevention
- Issue one ExecuteUpdate per table; never mix navigations into the root's setter.
- For TPT models, split updates across the table each property belongs to.
- Add a test asserting a single ExecuteUpdate touches one table.
When it happens
Trigger: Two SetProperty lambdas whose resolved ColumnExpressions have different TableAlias — e.g. SetProperty(o => o.OrderDate, ...) and SetProperty(o => o.Customer.ContactName, ...) (the latter lives on the Customers table). The TPT inheritance test (k => k.FoundOn vs k => k.Name) reproduces it.
Common situations: TPT inheritance where properties live on different mapped tables; updating a navigation's property in the same ExecuteUpdate as the root entity's property; combining owned/principal columns in one bulk update.
Related errors
- The element type of the result of '{dbFunction}' is mapped t
- The operation '{operation}' is being applied on entity type
- The operation '{operation}' is being applied on entity type
- The following lambda argument to 'SetProperty' does not repr
- 'ExecuteUpdate' is being used over a LINQ operator which isn
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/8dfa43911e3a8b03.
Report an issue: GitHub.