dotnet/efcore · error · InvalidOperationException

The number of key values

Error message

The number of key values ({valuesCount}) doesn't match the number of key columns ({columnsCount}) for the data deletion operation on '{table}'. Provide the same number of key values and key columns.

What it means

For a DeleteDataOperation EF checks that KeyColumns.Length equals the column dimension of KeyValues (KeyValues.GetLength(1)). The key shape must match the key columns so the generated WHERE clause targets the right number of columns per row; a mismatch is rejected before any DELETE is emitted.

Solutions

  1. Ensure each row of keyValues has one value per column in keyColumns, in matching order.
  2. Regenerate the migration so the scaffolder emits a consistent DeleteData.
  3. Double-check composite keys: a two-column key needs two values per deleted row.

Example fix

// before — composite key declared, single value per row
migrationBuilder.DeleteData(
    table: "Orders",
    keyColumns: new[] { "TenantId", "OrderId" },
    keyValues: new object[,] { { 1 }, { 2 } });

// after
migrationBuilder.DeleteData(
    table: "Orders",
    keyColumns: new[] { "TenantId", "OrderId" },
    keyValues: new object[,] { { 1, 100 }, { 2, 200 } });
Defensive patterns

Strategy: validation

Validate before calling

// Validate a DeleteDataOperation's key shape before generation
static void ValidateDelete(DeleteDataOperation op)
{
    if (op.KeyColumns.Length != op.KeyValues.GetLength(1))
        throw new ArgumentException(
            $"DeleteData on {op.Table}: {op.KeyColumns.Length} key columns vs " +
            $"{op.KeyValues.GetLength(1)} key value columns.");
}

Type guard

static bool DeleteKeyShapeOk(DeleteDataOperation op)
    => op.KeyColumns.Length == op.KeyValues.GetLength(1);

Prevention

When it happens

Trigger: migrationBuilder.DeleteData(table, keyColumns: new[] { "Id","TenantId" }, keyValues: new object[,] { { 1 } }) — key columns and key values arrays do not line up in width. Composite-key deletes edited by hand are the most common source.

Common situations: Manual edit of a migration after a key column was added/removed; composite-key delete where only one value per row was supplied; copy-paste between tables with different key shapes.

Related errors


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

Appendix: source

Thrown at src/EFCore.Relational/Migrations/MigrationsSqlGenerator.cs:969

        }

        builder.Append(sqlBuilder.ToString());
        EndStatement(builder);
    }

    /// <summary>
    ///     Generates the commands that correspond to the given operation.
    /// </summary>
    /// <param name="operation">The data operation to generate commands for.</param>
    /// <param name="model">The model.</param>
    /// <returns>The commands that correspond to the given operation.</returns>
    protected virtual IEnumerable<IReadOnlyModificationCommand> GenerateModificationCommands(
        DeleteDataOperation operation,
        IModel? model)
    {
        if (operation.KeyColumns.Length != operation.KeyValues.GetLength(1))
        {
            throw new InvalidOperationException(
                RelationalStrings.DeleteDataOperationValuesCountMismatch(
                    operation.KeyValues.GetLength(1), operation.KeyColumns.Length, FormatTable(operation.Table, operation.Schema)));
        }

        if (operation.KeyColumnTypes != null
            && operation.KeyColumns.Length != operation.KeyColumnTypes.Length)
        {
            throw new InvalidOperationException(
                RelationalStrings.DeleteDataOperationTypesCountMismatch(
                    operation.KeyColumnTypes.Length, operation.KeyColumns.Length, FormatTable(operation.Table, operation.Schema)));
        }

        if (operation.KeyColumnTypes == null
            && model == null)
        {
            throw new InvalidOperationException(
                RelationalStrings.DeleteDataOperationNoModel(
                    FormatTable(operation.Table, operation.Schema)));

View on GitHub (pinned to 3a2006ef56)