dotnet/efcore · error · InvalidOperationException

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

Error message

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

What it means

Thrown inside GenerateModificationCommands(UpdateDataOperation, ...) in src/EFCore.Relational/Migrations/MigrationsSqlGenerator.cs:1067 (message key UpdateDataOperationValuesCountMismatch). It compares operation.Columns.Length against operation.Values.GetLength(1) and throws InvalidOperationException when they differ. The SET clause assigns one value per column, so each value row must have exactly Columns.Length entries.

Source

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

    ///     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)));
        }

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

View on GitHub (pinned to dbf9771522)

Solutions

  1. Ensure every row of values has exactly operation.Columns.Length entries (values.GetLength(1) == columns.Length).
  2. Re-scaffold the migration to regenerate consistent values arrays.
  3. Drive seed changes through HasData so columns and values stay in sync.
  4. Audit: assert values.GetLength(1) == columns.Length for each UpdateData.

Example fix

// before (2 columns, 1 value):
migrationBuilder.UpdateData(
    table: "Users",
    keyColumns: new[] { "Id" },
    keyValues: new object[,] { { 1 } },
    columns: new[] { "Name", "Email" },
    values: new object[,] { { "Alice" } });

// after (aligned):
migrationBuilder.UpdateData(
    table: "Users",
    keyColumns: new[] { "Id" },
    keyValues: new object[,] { { 1 } },
    columns: new[] { "Name", "Email" },
    values: new object[,] { { "Alice", "a@x.com" } });
Defensive patterns

Strategy: validation

Validate before calling

static bool UpdateValueShapeIsValid(string[] columns, object[,] values)
{
    return values.GetLength(1) == columns.Length;
}

// usage before calling migrationBuilder.UpdateData
if (!UpdateValueShapeIsValid(columns, values))
    throw new InvalidOperationException("values second dimension must equal columns.Length");

Try / catch

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

Prevention

When it happens

Trigger: A migration calls migrationBuilder.UpdateData(columns: new[] { "A", "B" }, values: new object[,] { { 1 } }, ...) where the inner dimension of values does not equal columns.Length. Happens after editing a generated migration and dropping a value, or scaffolding HasData changes and hand-editing.

Common situations: Editing generated UpdateData and miscounting the values array. Changing the set of updated columns without updating values. Copy-paste of UpdateData blocks across entities.

Related errors


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