dotnet/efcore · error · InvalidOperationException

The number of key values ({valuesCount}) doesn't match the n

Error message

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

What it means

Thrown inside GenerateModificationCommands(UpdateDataOperation, ...) in src/EFCore.Relational/Migrations/MigrationsSqlGenerator.cs:1060 (message key UpdateDataOperationKeyValuesCountMismatch). It compares operation.KeyColumns.Length against operation.KeyValues.GetLength(1) and throws InvalidOperationException when they differ. UpdateData builds a WHERE clause per row from the key columns, so the per-row key value count must equal the key column count.

Source

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

        }

        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(
        UpdateDataOperation operation,
        IModel? model)
    {
        if (operation.KeyColumns.Length != operation.KeyValues.GetLength(1))
        {
            throw new InvalidOperationException(
                RelationalStrings.UpdateDataOperationKeyValuesCountMismatch(
                    operation.KeyValues.GetLength(1), operation.KeyColumns.Length, FormatTable(operation.Table, operation.Schema)));
        }

        if (operation.Columns.Length != operation.Values.GetLength(1))
        {
            throw new InvalidOperationException(
                RelationalStrings.UpdateDataOperationValuesCountMismatch(
                    operation.Values.GetLength(1), operation.Columns.Length, FormatTable(operation.Table, operation.Schema)));
        }

        if (operation.KeyValues.GetLength(0) != operation.Values.GetLength(0))
        {
            throw new InvalidOperationException(
                RelationalStrings.UpdateDataOperationRowCountMismatch(
                    operation.Values.GetLength(0), operation.KeyValues.GetLength(0), FormatTable(operation.Table, operation.Schema)));
        }

View on GitHub (pinned to dbf9771522)

Solutions

  1. Ensure every row of keyValues has exactly operation.KeyColumns.Length entries (keyValues.GetLength(1) == keyColumns.Length).
  2. Re-scaffold the migration so UpdateData key arrays match the current composite key.
  3. Manage seed data through HasData so EF scaffolds UpdateData consistently.
  4. Audit: assert keyValues.GetLength(1) == keyColumns.Length for each UpdateData.

Example fix

// before (composite key 2 columns, 1 key value):
migrationBuilder.UpdateData(
    table: "Members",
    keyColumns: new[] { "UserId", "GroupId" },
    keyValues: new object[,] { { 7 } },
    columns: new[] { "Role" },
    values: new object[,] { { "Admin" } });

// after (one key value per key column):
migrationBuilder.UpdateData(
    table: "Members",
    keyColumns: new[] { "UserId", "GroupId" },
    keyValues: new object[,] { { 7, 3 } },
    columns: new[] { "Role" },
    values: new object[,] { { "Admin" } });
Defensive patterns

Strategy: validation

Validate before calling

static bool UpdateKeyShapeIsValid(string[] keyColumns, object[,] keyValues)
{
    return keyValues.GetLength(1) == keyColumns.Length;
}

// usage before calling migrationBuilder.UpdateData
if (!UpdateKeyShapeIsValid(keyColumns, keyValues))
    throw new InvalidOperationException("keyValues second dimension must equal keyColumns.Length");

Try / catch

try
{
    await dbContext.Database.MigrateAsync();
}
catch (InvalidOperationException ex) when (ex.Message.Contains("number of key values") && ex.Message.Contains("data modification"))
{
    logger.LogError(ex, "An UpdateDataOperation has a keyValues/keyColumns length mismatch; fix the migration.");
    throw;
}

Prevention

When it happens

Trigger: A migration calls migrationBuilder.UpdateData(keyColumns: new[] { "Id", "TenantId" }, keyValues: new object[,] { { 1 } }, columns: new[] { "Name" }, values: new object[,] { { "x" } }) where the inner dimension of keyValues does not equal keyColumns.Length. Common after editing a generated migration for a composite-key entity.

Common situations: Hand-editing UpdateData calls for composite-key tables and miscounting key values. Modifying HasData seed rows for composite-key entities and then editing the scaffolded migration. Copy-paste of UpdateData blocks.

Related errors


AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06). Data as JSON: /api/errors/4ab0a146d41a03bd. Report an issue: GitHub.