{"record":{"id":"a37a711885ee264e","repo":"dotnet/efcore","slug":"the-complex-types-complextype1-and-complexty","errorCode":null,"errorMessage":"The complex types '{complexType1}' and '{complexType2}' are being assigned, but the latter is lacking property '{property}' of the former.","messagePattern":"The complex types '(.+?)' and '(.+?)' are being assigned, but the latter is lacking property '(.+?)' of the former\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteUpdate.cs","lineNumber":554,"sourceCode":"                    {\n                        throw new InvalidOperationException(\n                            RelationalStrings.ExecuteUpdateOverJsonIsNotSupported(nestedTargetComplexProperty.ComplexType.DisplayName()));\n                    }\n\n                    var nestedTargetExpression =\n                        (StructuralTypeShaperExpression)targetProjection.BindComplexProperty(nestedTargetComplexProperty);\n\n                    // If the value expression is a shaper with its own complex type (as opposed to a constant/parameter), we're assigning\n                    // one (modeled) column to another. In that case, find the corresponding property on the value complex type (which is\n                    // different than the target complex type, despite the two having the same CLR type, e.g. compare ShippingAddress to\n                    // BillingAddress).\n                    // Otherwise, if the value expression is a constant/parameter, just use the target complex property.\n                    var nestedValueComplexProperty = valueExpression is StructuralTypeShaperExpression\n                    {\n                        StructuralType: IComplexType valueNestedComplexType\n                    }\n                        ? valueNestedComplexType!.FindComplexProperty(nestedTargetComplexProperty.Name)\n                        ?? throw new InvalidOperationException(\n                            RelationalStrings.IncompatibleComplexTypesInAssignment(\n                                targetNestedComplexType.DisplayName(), valueNestedComplexType.DisplayName(),\n                                nestedTargetComplexProperty.Name))\n                        : nestedTargetComplexProperty;\n\n                    var nestedValueExpression = CreateComplexPropertyAccessExpression(valueExpression, nestedValueComplexProperty);\n\n                    ProcessComplexType(nestedTargetExpression, nestedValueExpression);\n                }\n\n                Expression CreatePropertyAccessExpression(Expression target, IProperty property)\n                {\n                    return target is LambdaExpression lambda\n                        ? Expression.Lambda(Core(lambda.Body, property), lambda.Parameters[0])\n                        : Core(target, property);\n\n                    Expression Core(Expression target, IProperty property)\n                    {","sourceCodeStart":536,"sourceCodeEnd":572,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteUpdate.cs#L536-L572","documentation":"Thrown when assigning one complex type to another during ExecuteUpdate and the value (right-hand) complex type is missing a property that exists on the target (left-hand) complex type. Because complex types are structurally compared property-by-property, an asymmetric shape is rejected.","triggerScenarios":"SetProperty(e => e.ShippingAddress, e => e.BillingAddress) where ShippingAddress and BillingAddress are different complex types that share a CLR type but one is missing a property defined on the other (e.g. ShippingAddress has Zip but BillingAddress does not). The nested-complex-property lookup returns null and fires this.","commonSituations":"Using two distinct complex types with the same CLR type but different property sets; refactoring one complex type without updating the other; assigning between complex types that drifted in schema.","solutions":["Make both complex types structurally identical (add the missing property to the value complex type, or remove it from the target).","Assign property-by-property instead of whole-complex-type assignment.","If using the same CLR type for both, ensure model configuration defines the same set of properties on each complex type."],"exampleFix":"// before\n.ExecuteUpdate(s => s.SetProperty(e => e.ShippingAddress, e => e.BillingAddress));\n// ShippingAddress has Zip, BillingAddress does not\n// after\nmodelBuilder.Entity<Order>().ComplexProperty(o => o.BillingAddress, b => b.Property(x => x.Zip).IsRequired());\n// or assign field by field\n.ExecuteUpdate(s => s\n    .SetProperty(e => e.ShippingAddress.Street, e => e.BillingAddress.Street)\n    .SetProperty(e => e.ShippingAddress.City, e => e.BillingAddress.City));","handlingStrategy":"validation","validationCode":"// Assert two complex types have identical property sets before assignment.\nstatic bool AreShapeCompatible(IComplexType a, IComplexType b)\n{\n    var ap = a.GetProperties().Select(p => p.Name).ToHashSet();\n    var bp = b.GetProperties().Select(p => p.Name).ToHashSet();\n    return ap.SetEquals(bp);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep complex types used in mutual assignment structurally identical.","Prefer per-property SetProperty over whole-complex-type assignment when shapes may differ.","Review complex-type configuration during schema refactors."],"tags":["efcore","executeupdate","complex-types","query-translation"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}