dotnet/efcore · error · InvalidOperationException
'{operation}' used over owned type '{entityType}' which is m
Error message
'{operation}' used over owned type '{entityType}' which is mapped to JSON; '{operation}' on JSON-mapped owned entities is not supported. Consider mapping your type as a complex type instead. What it means
Thrown when the property targeted by ExecuteUpdate/SetProperty belongs to an owned entity type that is mapped to JSON. Bulk updates inside JSON-mapped owned entities are not supported by the relational pipeline; the recommendation is to use complex types instead.
Source
Thrown at src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteUpdate.cs:319
{
if (IsMemberAccess(expression, QueryCompilationContext.Model, out var baseExpression, out var member)
&& _sqlTranslator.TryBindMember(
_sqlTranslator.Visit(baseExpression), member, out var target, out var targetProperty))
{
translation = target;
property = targetProperty;
return true;
}
translation = null;
property = null;
return false;
}
}
if (targetProperty.DeclaringType is IEntityType entityType && entityType.IsMappedToJson())
{
throw new InvalidOperationException(
RelationalStrings.ExecuteOperationOnOwnedJsonIsNotSupported("ExecuteUpdate", entityType.DisplayName()));
}
// Hack: when returning a StructuralTypeShaperExpression, _sqlTranslator returns it wrapped by a
// StructuralTypeReferenceExpression, which is supposed to be a private wrapper only with the SQL translator.
// Call TranslateProjection to unwrap it (need to look into getting rid StructuralTypeReferenceExpression altogether).
if (target is not CollectionResultExpression)
{
target = _sqlTranslator.TranslateProjection(target) is { } unwrappedTarget
? unwrappedTarget
: throw new InvalidOperationException(RelationalStrings.InvalidPropertyInSetProperty(propertySelector.Print()));
}
switch (target)
{
case ColumnExpression column:
{
Check.DebugAssert(column.TypeMapping is not null);View on GitHub (pinned to 3a2006ef56)
Solutions
- Remodel the JSON-owned entity as a complex type (OwnsComplexType / ComplexProperty) which supports ExecuteUpdate over its scalar members.
- Fall back to loading the entities, mutating, and SaveChanges for JSON-owned entities.
- Move the property you need to update out of the JSON-owned entity into the owning entity's table.
Example fix
// before
modelBuilder.Entity<RootEntity>()
.OwnsOne(r => r.RequiredAssociate, o => o.ToJson("Associate"));
await ctx.Set<RootEntity>().ExecuteUpdateAsync(s => s.SetProperty(r => r.RequiredAssociate.Name, "x"));
// after
modelBuilder.Entity<RootEntity>()
.ComplexProperty(r => r.RequiredAssociate);
await ctx.Set<RootEntity>().ExecuteUpdateAsync(s => s.SetProperty(r => r.RequiredAssociate.Name, "x")); Defensive patterns
Strategy: validation
Validate before calling
// Reject JSON-owned entities at config time when ExecuteUpdate is needed.
foreach (var et in ctx.Model.GetEntityTypes())
foreach (var nav in et.GetNavigations().Where(n => n.TargetEntityType.IsMappedToJson()))
{
logger.LogWarning("{EntityType}.{Nav} is JSON-owned; ExecuteUpdate unsupported.", et.Name, nav.Name);
} Prevention
- Prefer complex types over owned entities for JSON columns when bulk updates are needed.
- Centralize ownership configuration so JSON-owned entities are deliberate.
- Add a test that asserts ExecuteUpdate is never called against JSON-owned entities.
When it happens
Trigger: Configuring an owned entity with ToJson(...) (e.g. OwnsOne(x => x.RequiredAssociate, o => o.ToJson())) and then calling ExecuteUpdate with a setter that targets a property of that owned entity. The OwnedJsonBulkUpdateRelationalTestBase asserts this for both ExecuteDelete and ExecuteUpdate.
Common situations: Porting an owned-JSON model and trying to bulk-update nested objects; mixing JSON-owned entities with ExecuteUpdate after upgrading EF Core.
Related errors
- 'ExecuteUpdate' is being used over type '{structuralType}' w
- 'ExecuteUpdate' cannot currently set a property in a JSON co
- 'ExecuteUpdate' cannot currently set a property in a JSON co
- ExecuteUpdate over JSON columns is not supported when the co
- The provider in use does not support partial updates with Ex
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/884893bdf2264cf9.
Report an issue: GitHub.