dotnet/efcore · error · InvalidOperationException
The number of value rows ({valuesCount}) doesn't match the n
Error message
The number of value rows ({valuesCount}) doesn't match the number of key rows ({keyCount}) for the data modification operation on '{table}'. Provide the same number of value rows and key rows. What it means
Thrown inside GenerateModificationCommands(UpdateDataOperation, ...) in src/EFCore.Relational/Migrations/MigrationsSqlGenerator.cs:1074 (message key UpdateDataOperationRowCountMismatch). It compares operation.KeyValues.GetLength(0) against operation.Values.GetLength(0) and throws InvalidOperationException when they differ. UpdateData pairs each key row with one value row (UPDATE ... WHERE key = ...), so the number of key rows must equal the number of value rows.
Source
Thrown at src/EFCore.Relational/Migrations/MigrationsSqlGenerator.cs:1074
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)));
}
if (operation.ColumnTypes != null
&& operation.Columns.Length != operation.ColumnTypes.Length)
{
throw new InvalidOperationException(
RelationalStrings.UpdateDataOperationTypesCountMismatch(
operation.ColumnTypes.Length, operation.Columns.Length, FormatTable(operation.Table, operation.Schema)));View on GitHub (pinned to dbf9771522)
Solutions
- Ensure operation.Values.GetLength(0) == operation.KeyValues.GetLength(0) (one value row per key row).
- Re-scaffold the migration so rows stay paired.
- Manage seed data with HasData so EF keeps key rows and value rows aligned.
- Audit: assert values.GetLength(0) == keyValues.GetLength(0) for each UpdateData.
Example fix
// before (2 key rows, 1 value row):
migrationBuilder.UpdateData(
table: "Users",
keyColumns: new[] { "Id" },
keyValues: new object[,] { { 1 }, { 2 } },
columns: new[] { "Name" },
values: new object[,] { { "Alice" } });
// after (paired rows):
migrationBuilder.UpdateData(
table: "Users",
keyColumns: new[] { "Id" },
keyValues: new object[,] { { 1 }, { 2 } },
columns: new[] { "Name" },
values: new object[,] { { "Alice" }, { "Bob" } }); Defensive patterns
Strategy: validation
Validate before calling
static bool UpdateRowCountIsValid(object[,] keyValues, object[,] values)
{
return keyValues.GetLength(0) == values.GetLength(0);
}
// usage before calling migrationBuilder.UpdateData
if (!UpdateRowCountIsValid(keyValues, values))
throw new InvalidOperationException("number of value rows must equal number of key rows"); Try / catch
try
{
await dbContext.Database.MigrateAsync();
}
catch (InvalidOperationException ex) when (ex.Message.Contains("number of value rows") && ex.Message.Contains("data modification"))
{
logger.LogError(ex, "An UpdateDataOperation has mismatched key/value row counts; fix the migration.");
throw;
} Prevention
- Keep key rows and value rows paired one-to-one when editing UpdateData.
- Prefer HasData so EF scaffolds paired rows.
- Add a test asserting values.GetLength(0) == keyValues.GetLength(0) for each UpdateData.
- Re-scaffold migrations rather than hand-editing batch rows.
When it happens
Trigger: A migration calls migrationBuilder.UpdateData where the number of key rows in keyValues differs from the number of value rows in values. For example keyValues has 2 rows ({1},{2}) but values has 1 row ({"x"}). Happens when editing an UpdateData to add/remove a row on only one side.
Common situations: Hand-editing an UpdateData and adding a key row without its value row (or vice versa). Scaffolded multi-row HasData update that was partially edited. Misaligned batch updates in hand-authored migrations.
Related errors
- The number of key values ({valuesCount}) doesn't match the n
- The number of values ({valuesCount}) doesn't match the numbe
- The number of key column types ({typesCount}) doesn't match
- The number of column types ({typesCount}) doesn't match the
- The number of values ({valuesCount}) doesn't match the numbe
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/b8a23ed2b9a8593a.
Report an issue: GitHub.