{"record":{"id":"a9dd7f1fbae52a19","repo":"dotnet/efcore","slug":"executeoperationonkeylessentitytypewithunsupported-a9dd7f","errorCode":"ExecuteOperationOnKeylessEntityTypeWithUnsupportedOperator","errorMessage":"The operation '{operation}' cannot be performed on keyless entity type '{entityType}', since it contains an operator not natively supported by the database provider.","messagePattern":"The operation '(.+?)' cannot be performed on keyless entity type '(.+?)', since it contains an operator not natively supported by the database provider\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteUpdate.cs","lineNumber":98,"sourceCode":"            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);\n            var innerKeySelector = Expression.Lambda(\n                entitySource.CreateKeyValuesExpression(pk.Properties), firstPropertyLambdaExpression.Parameters);\n\n            var joinPredicate = CreateJoinPredicate(outer, outerKeySelector, inner, innerKeySelector);\n\n            Check.DebugAssert(joinPredicate != null, \"Join predicate shouldn't be null\");","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/dotnet/efcore/blob/dbf9771522148d61a2467854921bd5dc6f6e6916/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteUpdate.cs#L80-L116","documentation":"EF Core's ExecuteUpdate usually renders a single UPDATE...WHERE. When the query contains an operator the provider cannot natively express inside an UPDATE (join, group by, distinct, ordering, limit/offset), EF performs a 'pushdown': it wraps the query as a subquery and INNER JOINs it back to the target table on the primary key columns (see PushdownWithPkInnerJoinPredicate at line 62). A keyless entity type (HasNoKey, a view, or a raw SQL root) has no primary key, so the join predicate cannot be built and this error is thrown at line 96-102.","triggerScenarios":"Calling ExecuteUpdate over a keyless entity type (HasNoKey or ToView-only) combined with any operator that makes IsValidSelectExpressionForExecuteUpdate return false: OrderBy, Take/Skip (Limit/Offset), Distinct, GroupBy, Having, a multi-table FROM that is not a liftable INNER/CROSS JOIN. The error surfaces only when pushdown is required, not for trivial predicates.","commonSituations":"Bulk-updating a read model mapped with HasNoKey() or ToView(); chaining .OrderBy(...).Take(...).ExecuteUpdate(...) on a view-backed entity; querying through FromSql/TVFs whose shape is keyless and then updating; migrating a SaveChanges loop to ExecuteUpdate on an entity that was modeled keyless for query-only use.","solutions":["Remove the operator that forces pushdown (OrderBy, Take, Skip, Distinct, GroupBy) so the provider renders a native UPDATE over the keyless type.","Define a primary key on the entity type (HasKey in OnModelCreating or by convention) so the pushdown INNER JOIN has join columns.","If the entity is backed by a view, map it to a real mutable table (ToTable) instead of ToView.","Fall back to loading the entities and using SaveChanges, or issue the update via raw SQL (FromSql/ExecuteSqlRaw)."],"exampleFix":"// before\ndb.OrderSummaries.HasNoKey().ToView(\"OrderSummaries\")\n    .OrderBy(v => v.Total).Take(100)\n    .ExecuteUpdate(s => s.SetProperty(v => v.Archived, true));\n\n// after (drop pushdown-forcing operator so native UPDATE is used)\ndb.OrderSummaries\n    .Where(v => v.Archived == false)\n    .ExecuteUpdate(s => s.SetProperty(v => v.Archived, true));","handlingStrategy":"validation","validationCode":"// Before ExecuteUpdate, confirm the entity has a key and the query has no pushdown-forcing operator.\nvar entityType = db.Model.FindEntityType(typeof(MyView))!;\nbool keyless = entityType.FindPrimaryKey() is null;\nbool hasPushdownOperator = /* inspect your query chain for OrderBy/Take/Skip/Distinct/GroupBy/Join */;\nif (keyless && hasPushdownOperator)\n    throw new InvalidOperationException(\"ExecuteUpdate will fail: keyless entity + pushdown operator.\");","typeGuard":null,"tryCatchPattern":"try { await query.ExecuteUpdateAsync(s => ...); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"keyless entity type\"))\n{ /* fall back to SaveChanges or raw SQL, or remove the pushdown operator */ }","preventionTips":["Do not mark updatable entities with HasNoKey; reserve keyless types for true read-only views.","Avoid OrderBy/Distinct/GroupBy/Take/Skip immediately before ExecuteUpdate.","If you must update a view-backed type, map it ToTable instead of ToView."],"tags":["efcore","executeupdate","keyless","query-translation","pushdown"],"analyzedSha":"dbf9771522148d61a2467854921bd5dc6f6e6916","analyzedAt":"2026-08-06T20:46:03.226Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}