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 deletion operation on '{table}'. Provide the same number of key values and key columns. What it means
Thrown inside GenerateModificationCommands(DeleteDataOperation, ...) in src/EFCore.Relational/Migrations/MigrationsSqlGenerator.cs:969 (message key DeleteDataOperationValuesCountMismatch). It compares operation.KeyColumns.Length against operation.KeyValues.GetLength(1) and throws InvalidOperationException when they differ. DeleteData 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: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 dbf9771522)
Solutions
- Ensure every row in keyValues has exactly operation.KeyColumns.Length entries (the second dimension of the 2D array equals the keyColumns array length).
- Re-scaffold the migration so DeleteData arrays are regenerated for the current composite key.
- Use modelBuilder.Entity<T>().HasData(...) and remove rows there, letting EF scaffold the DeleteData consistently.
- Audit: assert keyValues.GetLength(1) == keyColumns.Length for each DeleteData.
Example fix
// before (composite key 2 columns, only 1 value):
migrationBuilder.DeleteData(
table: "Members",
keyColumns: new[] { "UserId", "GroupId" },
keyValues: new object[,] { { 7 } });
// after (one value per key column):
migrationBuilder.DeleteData(
table: "Members",
keyColumns: new[] { "UserId", "GroupId" },
keyValues: new object[,] { { 7, 3 } }); Defensive patterns
Strategy: validation
Validate before calling
static bool DeleteDataKeyShapeIsValid(string[] keyColumns, object[,] keyValues)
{
return keyValues.GetLength(1) == keyColumns.Length;
}
// usage before calling migrationBuilder.DeleteData
if (!DeleteDataKeyShapeIsValid(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 deletion"))
{
logger.LogError(ex, "A DeleteDataOperation has a keyValues/keyColumns length mismatch; fix the migration.");
throw;
} Prevention
- Prefer HasData management so EF scaffolds DeleteData with correct composite-key arrays.
- When editing DeleteData for composite keys, update keyColumns and every keyValues row together.
- Add a test asserting keyValues.GetLength(1) == keyColumns.Length for each DeleteData.
- Re-scaffold migrations after key changes rather than hand-editing.
When it happens
Trigger: A migration calls migrationBuilder.DeleteData(keyColumns: new[] { "Id", "TenantId" }, keyValues: new object[,] { { 1 } }) where the inner dimension of keyValues does not match the keyColumns length. Happens after editing a generated migration (e.g. composite key) and dropping a key value, or scaffolding HasData removal for a composite-key entity incorrectly.
Common situations: Editing generated DeleteData calls for composite-key tables and miscounting. Removing a HasData seed row for a composite-key entity and then hand-editing the migration. Copy-paste errors in hand-authored migrations.
Related errors
- The number of key column types ({typesCount}) doesn't match
- The number of values ({valuesCount}) doesn't match the numbe
- The number of column types ({typesCount}) doesn't match the
- The data deletion operation on '{table}' is not associated w
- The number of key values ({valuesCount}) doesn't match the n
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/ed25476e25319e00.
Report an issue: GitHub.