dotnet/efcore · error · InvalidOperationException

The operation '{operation}' cannot be performed on keyless e

Error message

The operation '{operation}' cannot be performed on keyless entity type '{entityType}', since it contains an operator not natively supported by the database provider.

What it means

When the query cannot be turned into a native single-table DELETE, EF falls back to a Contains/Any subquery over the primary key. This fallback requires a primary key; the throw fires when entityType.FindPrimaryKey() is null (keyless entity) and the query contained an operator the provider does not natively support in a DELETE. Keyless entities have no key to build the subquery with, so neither path works.

Source

Thrown at src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteDelete.cs:117

                {
                    throw new InvalidOperationException(
                        RelationalStrings.ExecuteDeleteOnTableSplitting(unwrappedTableExpression.Table.SchemaQualifiedName));
                }

                selectExpression.ReplaceProjection([]);
                selectExpression.ApplyProjection();

                return new DeleteExpression(unwrappedTableExpression, selectExpression);
            }
        }

        // We can't translate to a simple delete (e.g. the provider doesn't support one of the clauses).
        // As a fallback, we place the original query in a Contains subquery, which will get translated via the regular entity equality/
        // containment mechanism (InExpression for non-composite keys, Any for composite keys)
        var pk = entityType.FindPrimaryKey();
        if (pk == null)
        {
            throw new InvalidOperationException(
                RelationalStrings.ExecuteOperationOnKeylessEntityTypeWithUnsupportedOperator(
                    nameof(EntityFrameworkQueryableExtensions.ExecuteDelete),
                    entityType.DisplayName()));
        }

        var clrType = entityType.ClrType;
        var entityParameter = Expression.Parameter(clrType);
        var predicateBody = Expression.Call(QueryableMethods.Contains.MakeGenericMethod(clrType), source, entityParameter);

        var newSource = Expression.Call(
            QueryableMethods.Where.MakeGenericMethod(clrType),
            new EntityQueryRootExpression(entityType),
            Expression.Quote(Expression.Lambda(predicateBody, entityParameter)));

        return TranslateExecuteDelete((ShapedQueryExpression)Visit(newSource));

        static bool AreOtherNonOwnedEntityTypesInTheTable(IEntityType rootType, ITableBase table)
        {

View on GitHub (pinned to 3a2006ef56)

Solutions

  1. Define a primary key on the entity (remove HasNoKey / configure a key) so the subquery fallback works.
  2. Simplify the query so it falls inside the provider's natively-supported DELETE shape (single table + WHERE predicate only).
  3. Issue the delete via raw SQL against the underlying table.

Example fix

// before (keyless + unsupported operator -> 597)
modelBuilder.Entity<ThingView>().HasNoKey().ToView("v_things");
await db.Set<ThingView>().OrderBy(t => t.Id).Take(100).ExecuteDeleteAsync();
// after (simplify to supported predicate)
await db.Set<ThingView>().Where(t => t.Old).ExecuteDeleteAsync();
// or give the entity a key and a table mapping
Defensive patterns

Strategy: validation

Validate before calling

// For keyless entities, restrict ExecuteDelete to a simple predicate the provider renders natively.
var et = db.Model.FindEntityType(typeof(TEntity))!;
if (et.FindPrimaryKey() is null)
{
    Console.WriteLine($"{et.Name} is keyless; keep ExecuteDelete sources to a simple Where predicate, "
                      + "or define a key, or use raw SQL.");
}

Prevention

When it happens

Trigger: context.Set<KeylessView>().Where(...).OrderBy(...).Take(...).ExecuteDelete() (or any unsupported operator beyond a simple predicate) where KeylessView is mapped HasNoKey. The native DELETE path fails on the unsupported operator, and the subquery fallback fails on the missing key.

Common situations: Database views mapped as keyless entities; query-only types; missing key configuration on what was intended to be an updatable table.

Related errors


AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11). Data as JSON: /api/errors/38ed33c1b342b624. Report an issue: GitHub.