dotnet/efcore · error · InvalidOperationException
JsonExecuteUpdateNotSupportedWithOwnedEntities
JsonExecuteUpdateNotSupportedWithOwnedEntities
Error message
ExecuteUpdate over JSON columns is not supported when the column is mapped as an owned entity. Map the column as a complex type instead.
What it means
ProcessStructuralJsonSetter (line 663-739) handles updating a JSON document through a JsonQueryExpression. It only supports complex types (IComplexType). If the JSON structural type is an owned entity type (not a complex type), partial JSON updates are unsupported and JsonExecuteUpdateNotSupportedWithOwnedEntities is thrown at line 668-670, with a message recommending complex types.
Source
Thrown at src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteUpdate.cs:669
StructuralTypeShaperExpression
{
StructuralType: IComplexType,
ValueBufferExpression: StructuralTypeProjectionExpression projection
}
=> projection.BindComplexProperty(complexProperty),
_ => throw new UnreachableException()
};
}
}
void ProcessStructuralJsonSetter(JsonQueryExpression jsonQuery)
{
var jsonColumn = jsonQuery.JsonColumn;
if (jsonQuery.StructuralType is not IComplexType complexType)
{
throw new InvalidOperationException(RelationalStrings.JsonExecuteUpdateNotSupportedWithOwnedEntities);
}
Check.DebugAssert(jsonColumn.TypeMapping is not null);
ProcessColumn(jsonColumn, targetProperty);
var translatedValue = TranslateSetterValueSelector(source, valueSelector, jsonQuery.Type);
SqlExpression? serializedValue;
switch (translatedValue)
{
// When an object is instantiated inline (e.g. SetProperty(c => c.ShippingAddress, c => new Address { ... })), we get a SqlConstantExpression
// with the .NET instance. Serialize it to JSON and replace the constant (note that the type mapping is inferred from the
// JSON column on other side - important for e.g. nvarchar vs. json columns)
case SqlConstantExpression { Value: var value }:
serializedValue = new SqlConstantExpression(
RelationalJsonUtilities.SerializeComplexTypeToJson(complexType, value, jsonQuery.IsCollection),View on GitHub (pinned to dbf9771522)
Solutions
- Remodel the JSON-mapped owned entity as a complex type (ComplexProperty) so partial JSON ExecuteUpdate is supported.
- For owned JSON entities, load and SaveChanges instead of ExecuteUpdate.
- Update the entire JSON column via raw SQL if a partial update is required.
Example fix
// before (Owned is OwnsOne(...).ToJson())
modelBuilder.Entity<Order>().OwnsOne(o => o.Details, d => d.ToJson());
db.Orders.ExecuteUpdate(s => s.SetProperty(
o => o.Details.Notes, "x"));
// after (Details is a complex type)
modelBuilder.Entity<Order>().ComplexProperty(o => o.Details);
db.Orders.ExecuteUpdate(s => s.SetProperty(
o => o.Details.Notes, "x")); Defensive patterns
Strategy: validation
Validate before calling
// Confirm the JSON structural type is a complex type, not an owned entity.
bool isComplex = jsonStructuralType is IComplexType;
if (!isComplex) throw new InvalidOperationException("Remodel JSON owned entity as a complex type for ExecuteUpdate."); Try / catch
try { await q.ExecuteUpdateAsync(s => s.SetProperty(e => e.Details.X, v)); }
catch (InvalidOperationException ex) when (ex.Message.Contains("owned entities"))
{ /* switch OwnsOne().ToJson() to ComplexProperty, or use SaveChanges */ } Prevention
- Use complex types (not JSON-owned entities) for JSON data needing bulk updates.
- Migrate OwnsOne().ToJson() to ComplexProperty where ExecuteUpdate is required.
- Keep owned JSON entities read-only or SaveChanges-only.
When it happens
Trigger: ExecuteUpdate whose property selector resolves to a JSON-mapped owned entity (OwnsOne/OwnsMany with ToJson), targeting either the whole owned entity or a path inside it, where the structural type at that path is an owned entity rather than a complex type.
Common situations: Pre-complex-type models that use OwnsOne().ToJson() and attempt ExecuteUpdate on the JSON document or sub-paths; migrating an owned JSON entity and expecting ExecuteUpdate support that only complex types get.
Related errors
- ExecuteOperationOnOwnedJsonIsNotSupported
- ExecuteUpdateOverJsonIsNotSupported
- ExecuteUpdateCannotSetJsonPropertyToNonJsonColumn
- ExecuteUpdateCannotSetJsonPropertyToArbitraryExpression
- IncompatibleComplexTypesInAssignment
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/223be3c2a2a5e085.
Report an issue: GitHub.