{"record":{"id":"b8a23ed2b9a8593a","repo":"dotnet/efcore","slug":"the-number-of-value-rows-valuescount-doesn-t-m","errorCode":null,"errorMessage":"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.","messagePattern":"The number of value rows \\((.+?)\\) doesn't match the number of key rows \\((.+?)\\) for the data modification operation on '(.+?)'\\. Provide the same number of value rows and key rows\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Migrations/MigrationsSqlGenerator.cs","lineNumber":1074,"sourceCode":"        IModel? model)\n    {\n        if (operation.KeyColumns.Length != operation.KeyValues.GetLength(1))\n        {\n            throw new InvalidOperationException(\n                RelationalStrings.UpdateDataOperationKeyValuesCountMismatch(\n                    operation.KeyValues.GetLength(1), operation.KeyColumns.Length, FormatTable(operation.Table, operation.Schema)));\n        }\n\n        if (operation.Columns.Length != operation.Values.GetLength(1))\n        {\n            throw new InvalidOperationException(\n                RelationalStrings.UpdateDataOperationValuesCountMismatch(\n                    operation.Values.GetLength(1), operation.Columns.Length, FormatTable(operation.Table, operation.Schema)));\n        }\n\n        if (operation.KeyValues.GetLength(0) != operation.Values.GetLength(0))\n        {\n            throw new InvalidOperationException(\n                RelationalStrings.UpdateDataOperationRowCountMismatch(\n                    operation.Values.GetLength(0), operation.KeyValues.GetLength(0), FormatTable(operation.Table, operation.Schema)));\n        }\n\n        if (operation.KeyColumnTypes != null\n            && operation.KeyColumns.Length != operation.KeyColumnTypes.Length)\n        {\n            throw new InvalidOperationException(\n                RelationalStrings.UpdateDataOperationKeyTypesCountMismatch(\n                    operation.KeyColumnTypes.Length, operation.KeyColumns.Length, FormatTable(operation.Table, operation.Schema)));\n        }\n\n        if (operation.ColumnTypes != null\n            && operation.Columns.Length != operation.ColumnTypes.Length)\n        {\n            throw new InvalidOperationException(\n                RelationalStrings.UpdateDataOperationTypesCountMismatch(\n                    operation.ColumnTypes.Length, operation.Columns.Length, FormatTable(operation.Table, operation.Schema)));","sourceCodeStart":1056,"sourceCodeEnd":1092,"githubUrl":"https://github.com/dotnet/efcore/blob/dbf9771522148d61a2467854921bd5dc6f6e6916/src/EFCore.Relational/Migrations/MigrationsSqlGenerator.cs#L1056-L1092","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (2 key rows, 1 value row):\nmigrationBuilder.UpdateData(\n    table: \"Users\",\n    keyColumns: new[] { \"Id\" },\n    keyValues: new object[,] { { 1 }, { 2 } },\n    columns: new[] { \"Name\" },\n    values: new object[,] { { \"Alice\" } });\n\n// after (paired rows):\nmigrationBuilder.UpdateData(\n    table: \"Users\",\n    keyColumns: new[] { \"Id\" },\n    keyValues: new object[,] { { 1 }, { 2 } },\n    columns: new[] { \"Name\" },\n    values: new object[,] { { \"Alice\" }, { \"Bob\" } });","handlingStrategy":"validation","validationCode":"static bool UpdateRowCountIsValid(object[,] keyValues, object[,] values)\n{\n    return keyValues.GetLength(0) == values.GetLength(0);\n}\n\n// usage before calling migrationBuilder.UpdateData\nif (!UpdateRowCountIsValid(keyValues, values))\n    throw new InvalidOperationException(\"number of value rows must equal number of key rows\");","typeGuard":null,"tryCatchPattern":"try\n{\n    await dbContext.Database.MigrateAsync();\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"number of value rows\") && ex.Message.Contains(\"data modification\"))\n{\n    logger.LogError(ex, \"An UpdateDataOperation has mismatched key/value row counts; fix the migration.\");\n    throw;\n}","preventionTips":["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."],"tags":["migrations","data-seeding","update-data","validation","invalidoperation"],"analyzedSha":"dbf9771522148d61a2467854921bd5dc6f6e6916","analyzedAt":"2026-08-06T20:46:03.226Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}