dotnet/efcore · error · NotSupportedException

SQL generation for the operation '{operation}' is not suppor

Error message

SQL generation for the operation '{operation}' is not supported by the current database provider. Database providers must implement the appropriate method in 'MigrationsSqlGenerator' to support this operation.

What it means

Thrown by the base MigrationsSqlGenerator.Generate(AlterColumnOperation, ...) overload in src/EFCore.Relational/Migrations/MigrationsSqlGenerator.cs:310. Altering an existing column's type, nullability, or default has no SQL-standard syntax, so the relational base class throws NotSupportedException by default. Each database provider is expected to override this method to emit provider-specific ALTER COLUMN SQL (e.g. SQL Server ALTER TABLE ... ALTER COLUMN). If your active provider does not override it, any migration that contains an AlterColumnOperation cannot be applied.

Source

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

        EndStatement(builder);
    }

    /// <summary>
    ///     Can be overridden by database providers to build commands for the given <see cref="AlterColumnOperation" />
    ///     by making calls on the given <see cref="MigrationCommandListBuilder" />.
    /// </summary>
    /// <remarks>
    ///     Note that the default implementation of this method throws <see cref="NotSupportedException" />. Providers
    ///     must override if they are to support this kind of operation.
    /// </remarks>
    /// <param name="operation">The operation.</param>
    /// <param name="model">The target model which may be <see langword="null" /> if the operations exist without a model.</param>
    /// <param name="builder">The command builder to use to build the commands.</param>
    protected virtual void Generate(
        AlterColumnOperation operation,
        IModel? model,
        MigrationCommandListBuilder builder)
        => throw new NotSupportedException(RelationalStrings.MigrationSqlGenerationMissing(nameof(AlterColumnOperation)));

    /// <summary>
    ///     Can be overridden by database providers to build commands for the given <see cref="AlterDatabaseOperation" />
    ///     by making calls on the given <see cref="MigrationCommandListBuilder" />.
    /// </summary>
    /// <remarks>
    ///     Note that there is no default implementation of this method. Providers must override if they are to
    ///     support this kind of operation.
    /// </remarks>
    /// <param name="operation">The operation.</param>
    /// <param name="model">The target model which may be <see langword="null" /> if the operations exist without a model.</param>
    /// <param name="builder">The command builder to use to build the commands.</param>
    protected virtual void Generate(
        AlterDatabaseOperation operation,
        IModel? model,
        MigrationCommandListBuilder builder)
    {
    }

View on GitHub (pinned to dbf9771522)

Solutions

  1. Switch to a first-party provider that implements AlterColumnOperation (Microsoft.EntityFrameworkCore.SqlServer, Npgsql.EntityFrameworkCore.PostgreSQL, or the current Pomelo/Oracle providers), which all override this method.
  2. Upgrade your database provider NuGet package to a version whose MigrationsSqlGenerator overrides Generate(AlterColumnOperation, ...).
  3. If you author a custom provider, override protected virtual void Generate(AlterColumnOperation operation, IModel? model, MigrationCommandListBuilder builder) in your provider's MigrationsSqlGenerator subclass and emit the correct ALTER COLUMN SQL.
  4. Rewrite the offending migration to drop and recreate the column/table instead of using AlterColumn (DropColumn + AddColumn, or a full Sql(...) rebuild), avoiding the unsupported operation entirely.
  5. Split the model change so it no longer produces an AlterColumnOperation (e.g. separate add/remove rather than alter).

Example fix

// before (custom provider lacking the override):
// migration generated by:
migrationBuilder.AlterColumn<string>("Name", table: "Users", type: "nvarchar(200)", nullable: false);

// after (override in your provider's MigrationsSqlGenerator):
protected override void Generate(
    AlterColumnOperation operation,
    IModel? model,
    MigrationCommandListBuilder builder)
{
    builder
        .Append("ALTER TABLE ")
        .Append(Dependencies.SqlGenerationHelper.DelimitIdentifier(operation.Table, operation.Schema))
        .Append(" ALTER COLUMN ")
        .Append(Dependencies.SqlGenerationHelper.DelimitIdentifier(operation.Name))
        .Append(" ")
        .Append(operation.ColumnType ?? operation.ComputedColumnSql ?? "TEXT");
    builder.AppendLine(Dependencies.SqlGenerationHelper.StatementTerminator);
    EndStatement(builder);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// No public capability table exists; validate by probing the generator's overrides via reflection
Type generatorType = dbContext.Database.GetService<MigrationsSqlGenerator>().GetType();
bool supportsAlterColumn = generatorType.GetMethod(
    "Generate",
    BindingFlags.Instance | BindingFlags.NonPublic,
    binder: null,
    types: new[] { typeof(AlterColumnOperation), typeof(IModel), typeof(MigrationCommandListBuilder) },
    modifiers: null)!.DeclaringType != typeof(MigrationsSqlGenerator);
if (!supportsAlterColumn)
    Console.WriteLine($"Provider {generatorType} does not override AlterColumnOperation; migration may throw.");

Try / catch

try
{
    await dbContext.Database.MigrateAsync();
}
catch (NotSupportedException ex) when (ex.Message.Contains("AlterColumnOperation"))
{
    logger.LogError(ex, "Provider cannot ALTER COLUMN; rewrite the migration to drop+recreate the column or switch providers.");
    throw;
}

Prevention

When it happens

Trigger: Running Database.Migrate()/MigrateAsync() (or dotnet ef database update) against a provider whose MigrationsSqlGenerator does not override Generate(AlterColumnOperation, IModel, MigrationCommandListBuilder), while a pending migration contains an AlterColumnOperation (e.g. scaffolded after you change a property's column type, nullability, or default value, or hand-authored via migrationBuilder.AlterColumn<T>(...)). Typical sources: a custom/incomplete provider that omits the override; a very old provider package version that predates ALTER COLUMN support; SQLite without a table-rebuild rewrite extension in some scenarios.

Common situations: Building or maintaining a custom EF Core database provider and forgetting to override the AlterColumnOperation method. Pinning an old provider NuGet package that lacks ALTER COLUMN support. Mixing a migration scaffolded for one provider (e.g. SQL Server) and trying to apply it to a different, less capable provider. Renaming/changing a property type in the model and letting the scaffolder emit AlterColumn into a migration that then runs against an unsupported provider.

Related errors


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