{"record":{"id":"d05de8024942868a","repo":"dotnet/efcore","slug":"executeupdatesubquerynotsupportedovercomplextypes","errorCode":"ExecuteUpdateSubqueryNotSupportedOverComplexTypes","errorMessage":"'ExecuteUpdate' is being used over a LINQ operator which isn't natively supported by the database; this cannot be translated because complex type '{complexType}' is projected out. Rewrite your query to project out the containing entity type instead.","messagePattern":"'ExecuteUpdate' is being used over a LINQ operator which isn't natively supported by the database; this cannot be translated because complex type '(.+?)' is projected out\\. Rewrite your query to project out the containing entity type instead\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteUpdate.cs","lineNumber":92,"sourceCode":"            // the first property selector.\n\n            // The following mechanism for extracting the entity type from property selectors only supports simple member access,\n            // EF.Function, etc. We also unwrap casts to interface/base class (#29618). Note that owned IncludeExpressions have already\n            // been pruned from the source before remapping the lambda (#28727).\n            var firstPropertySelector = setters[0].PropertySelector;\n            if (!IsMemberAccess(\n                    RemapLambdaBody(source, firstPropertySelector).UnwrapTypeConversion(out _),\n                    RelationalDependencies.Model,\n                    out var baseExpression)\n                || _sqlTranslator.TranslateProjection(baseExpression) is not StructuralTypeShaperExpression shaper)\n            {\n                throw new InvalidOperationException(RelationalStrings.InvalidPropertyInSetProperty(firstPropertySelector));\n            }\n\n            // TODO: #36336\n            if (shaper.StructuralType is not IEntityType entityType)\n            {\n                throw new InvalidOperationException(\n                    RelationalStrings.ExecuteUpdateSubqueryNotSupportedOverComplexTypes(shaper.StructuralType.DisplayName()));\n            }\n\n            if (entityType.FindPrimaryKey() is not { } pk)\n            {\n                throw new InvalidOperationException(\n                    RelationalStrings.ExecuteOperationOnKeylessEntityTypeWithUnsupportedOperator(\n                        nameof(EntityFrameworkQueryableExtensions.ExecuteUpdate),\n                        entityType.DisplayName()));\n            }\n\n            // Generate the INNER JOIN around the original query, on the PK properties.\n            var outer = (ShapedQueryExpression)Visit(new EntityQueryRootExpression(entityType));\n            var inner = source;\n            var outerParameter = Expression.Parameter(entityType.ClrType);\n            var outerKeySelector = Expression.Lambda(outerParameter.CreateKeyValuesExpression(pk.Properties), outerParameter);\n            var firstPropertyLambdaExpression = setters[0].PropertySelector;\n            var entitySource = GetEntitySource(RelationalDependencies.Model, firstPropertyLambdaExpression.Body);","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/dotnet/efcore/blob/dbf9771522148d61a2467854921bd5dc6f6e6916/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteUpdate.cs#L74-L110","documentation":"Thrown on the ExecuteUpdate pushdown path when the shaper resolved from the property selector binds to a complex type (StructuralType is IComplexType) rather than an entity type. The pushdown rewrites the query via an INNER JOIN on the primary key, but complex types have no primary key, so the rewrite cannot be performed. The message advises projecting the containing entity instead.","triggerScenarios":"Calling ExecuteUpdate where a SetProperty lambda projects out a complex type directly (e.g. SetProperty(c => c.Address, ...) where Address is a ComplexProperty) combined with a LINQ operator the provider cannot natively translate, forcing the pushdown path.","commonSituations":"Adopting complex types (ComplexProperty) and using ExecuteUpdate with a non-translatable operator (GroupBy, join, distinct) before it; trying to bulk-assign a whole complex type value.","solutions":["Rewrite the query to project the containing entity type instead of the complex type: SetProperty over the entity parameter and its scalar sub-properties.","Remove the non-translatable LINQ operator before ExecuteUpdate so the native path is used (no pushdown).","Set individual scalar properties of the complex type rather than the whole complex object.","Load and update entities via SaveChanges if the complex-type assignment is essential."],"exampleFix":"// before - complex type projected + non-translatable operator\nawait db.Orders\n    .Where(o => o.Tags.Contains(\"x\"))\n    .Distinct()\n    .ExecuteUpdateAsync(s => s.SetProperty(o => o.Address, o => new Address { City = \"X\" }));\n// after - project the entity, set scalar sub-properties, drop the unsupported operator\nawait db.Orders\n    .Where(o => o.Tags.Contains(\"x\"))\n    .ExecuteUpdateAsync(s => s.SetProperty(o => o.Address.City, \"X\"));","handlingStrategy":"validation","validationCode":"// Detect complex-type projection in a setter selector\nstatic bool TargetsComplexType(LambdaExpression selector, IModel model)\n{\n    if (selector.Body is MemberExpression me)\n    {\n        var et = model.FindEntityType(me.Expression?.Type);\n        if (et?.FindComplexProperty(me.Member.Name) is not null) return true;\n    }\n    return false;\n}\n\nif (TargetsComplexType(setters[0].PropertySelector, db.Model))\n    throw new InvalidOperationException(\"Project the containing entity; set scalar sub-properties of the complex type.\");","typeGuard":null,"tryCatchPattern":"try { await query.ExecuteUpdateAsync(setters); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"complex type\"))\n{\n    // rewrite setters to target scalar sub-properties of the entity, then retry\n    await query.ExecuteUpdateAsync(s => s.SetProperty(e => EF.Property<string>(e.Address, \"City\"), \"X\"));\n}","preventionTips":["Project the containing entity in ExecuteUpdate; set complex-type sub-properties individually.","Remove non-translatable operators (Distinct, GroupBy, joins) before ExecuteUpdate to avoid the pushdown path.","Avoid assigning whole complex-type instances in SetProperty.","Use SaveChanges when whole-complex-type assignment is required."],"tags":["executeupdate","complex-types","pushdown","setproperty","bulk-operations"],"analyzedSha":"dbf9771522148d61a2467854921bd5dc6f6e6916","analyzedAt":"2026-08-06T20:46:03.226Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}