{"record":{"id":"223be3c2a2a5e085","repo":"dotnet/efcore","slug":"jsonexecuteupdatenotsupportedwithownedentities","errorCode":"JsonExecuteUpdateNotSupportedWithOwnedEntities","errorMessage":"ExecuteUpdate over JSON columns is not supported when the column is mapped as an owned entity. Map the column as a complex type instead.","messagePattern":"ExecuteUpdate over JSON columns is not supported when the column is mapped as an owned entity\\. Map the column as a complex type instead\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteUpdate.cs","lineNumber":669,"sourceCode":"                            StructuralTypeShaperExpression\n                            {\n                                StructuralType: IComplexType,\n                                ValueBufferExpression: StructuralTypeProjectionExpression projection\n                            }\n                                => projection.BindComplexProperty(complexProperty),\n\n                            _ => throw new UnreachableException()\n                        };\n                }\n            }\n\n            void ProcessStructuralJsonSetter(JsonQueryExpression jsonQuery)\n            {\n                var jsonColumn = jsonQuery.JsonColumn;\n\n                if (jsonQuery.StructuralType is not IComplexType complexType)\n                {\n                    throw new InvalidOperationException(RelationalStrings.JsonExecuteUpdateNotSupportedWithOwnedEntities);\n                }\n\n                Check.DebugAssert(jsonColumn.TypeMapping is not null);\n\n                ProcessColumn(jsonColumn, targetProperty);\n\n                var translatedValue = TranslateSetterValueSelector(source, valueSelector, jsonQuery.Type);\n\n                SqlExpression? serializedValue;\n\n                switch (translatedValue)\n                {\n                    // When an object is instantiated inline (e.g. SetProperty(c => c.ShippingAddress, c => new Address { ... })), we get a SqlConstantExpression\n                    // with the .NET instance. Serialize it to JSON and replace the constant (note that the type mapping is inferred from the\n                    // JSON column on other side - important for e.g. nvarchar vs. json columns)\n                    case SqlConstantExpression { Value: var value }:\n                        serializedValue = new SqlConstantExpression(\n                            RelationalJsonUtilities.SerializeComplexTypeToJson(complexType, value, jsonQuery.IsCollection),","sourceCodeStart":651,"sourceCodeEnd":687,"githubUrl":"https://github.com/dotnet/efcore/blob/dbf9771522148d61a2467854921bd5dc6f6e6916/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteUpdate.cs#L651-L687","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (Owned is OwnsOne(...).ToJson())\nmodelBuilder.Entity<Order>().OwnsOne(o => o.Details, d => d.ToJson());\ndb.Orders.ExecuteUpdate(s => s.SetProperty(\n    o => o.Details.Notes, \"x\"));\n\n// after (Details is a complex type)\nmodelBuilder.Entity<Order>().ComplexProperty(o => o.Details);\ndb.Orders.ExecuteUpdate(s => s.SetProperty(\n    o => o.Details.Notes, \"x\"));","handlingStrategy":"validation","validationCode":"// Confirm the JSON structural type is a complex type, not an owned entity.\nbool isComplex = jsonStructuralType is IComplexType;\nif (!isComplex) throw new InvalidOperationException(\"Remodel JSON owned entity as a complex type for ExecuteUpdate.\");","typeGuard":null,"tryCatchPattern":"try { await q.ExecuteUpdateAsync(s => s.SetProperty(e => e.Details.X, v)); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"owned entities\"))\n{ /* switch OwnsOne().ToJson() to ComplexProperty, or use SaveChanges */ }","preventionTips":["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."],"tags":["efcore","executeupdate","json","owned-entity","complex-type"],"analyzedSha":"dbf9771522148d61a2467854921bd5dc6f6e6916","analyzedAt":"2026-08-06T20:46:03.226Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}