dotnet/efcore · error · InvalidOperationException

The data modification operation on

Error message

The data modification operation on '{table}' is not associated with a model. Either add a model to the migration, or specify the column types in all data operations.

What it means

Thrown for an UpdateData operation when neither KeyColumnTypes nor a model is available. EF cannot resolve store types for key/value parameters without at least one of them. Update also requires ColumnTypes-or-model for the value columns, but this specific guard fires on the key side first.

Solutions

  1. Pass keyColumnTypes (and columnTypes) for every column referenced so EF can resolve mappings without a model.
  2. Run the migration through the standard Migrator which supplies the model.
  3. Re-scaffold the migration via dotnet ef migrations add so BuildTargetModel is emitted.

Example fix

// before
migrationBuilder.UpdateData(
    table: "Users",
    keyColumns: new[] { "Id" },
    keyValues: new object[,] { { 10 } },
    columns: new[] { "Name" },
    values: new object[,] { { "Ann" } });

// after
migrationBuilder.UpdateData(
    table: "Users",
    keyColumns: new[] { "Id" },
    keyColumnTypes: new[] { "int" },
    keyValues: new object[,] { { 10 } },
    columns: new[] { "Name" },
    columnTypes: new[] { "nvarchar(max)" },
    values: new object[,] { { "Ann" } });
Defensive patterns

Strategy: validation

Validate before calling

static void EnsureUpdateDataResolvable(string[]? keyColumnTypes, string[]? columnTypes, IModel? model, string table)
{
    if (model is null && (keyColumnTypes is null || columnTypes is null))
        throw new InvalidOperationException($"{table}: UpdateData needs a model, or both keyColumnTypes and columnTypes.");
}

Prevention

When it happens

Trigger: migrationBuilder.UpdateData(...) with no keyColumnTypes, executed in a pipeline that does not pass a target model. Triggered when operation.KeyColumnTypes == null && model == null.

Common situations: Manual use of MigrationBuilder outside the Migrator. Design-time operations on a migrations-only assembly with no DbContext. Stripping BuildTargetModel from a generated migration.

Related errors


AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11). Data as JSON: /api/errors/dc4b160bf1ed2af9. Report an issue: GitHub.

Appendix: source

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

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

        if (operation.KeyColumnTypes == null
            && model == null)
        {
            throw new InvalidOperationException(
                RelationalStrings.UpdateDataOperationNoModel(
                    FormatTable(operation.Table, operation.Schema)));
        }

        var keyPropertyMappings = operation.KeyColumnTypes == null
            ? GetPropertyMappings(operation.KeyColumns, operation.Table, operation.Schema, model)
            : null;
        var propertyMappings = operation.ColumnTypes == null
            ? GetPropertyMappings(operation.Columns, operation.Table, operation.Schema, model)
            : null;

        for (var i = 0; i < operation.KeyValues.GetLength(0); i++)
        {
            var modificationCommand = Dependencies.ModificationCommandFactory.CreateNonTrackedModificationCommand(
                new NonTrackedModificationCommandParameters(operation.Table, operation.Schema, SensitiveLoggingEnabled));
            modificationCommand.EntityState = EntityState.Modified;

            for (var j = 0; j < operation.KeyColumns.Length; j++)

View on GitHub (pinned to 3a2006ef56)