Automatic reversal

Fluent operations can describe a supported reverse sequence; Classic migrations author it directly.

Examples use Classic and Fluent tabs. Your choice follows you through the manual.

Creation and its reverse

AutoReversingMigration derives reverse operations in reverse order and validates reversal support before its first change. The Classic equivalent makes the Down operation explicit. Both examples below create the same table and remove it on downgrade.

A reversible table creation

Classic

using System;
using System.Data;
using DotNetProjects.Migrator;
using DotNetProjects.Migrator.Framework;

[Migration(3)]
public class CreateNotes : Migration
{
    public override void Up() => Database.AddTable("Notes", new Column("Text", DbType.String, 500));
    public override void Down() => Database.RemoveTable("Notes");
}

Fluent

using System;
using System.Data;
using DotNetProjects.Migrator;
using DotNetProjects.Migrator.Framework;
using DotNetProjects.Migrator.Framework.Fluent;

[Migration(3)]
public class CreateNotes : AutoReversingMigration
{
    public override void BuildUp(MigrationBuilder migration)
        => migration.Create.Table("Notes").WithColumn("Text").AsString(500);
}

Choose one authoring style

What needs an authored reverse

Destructive changes, data operations, SQL and callbacks require explicit reverse behavior. Reverse support is narrower than execution support. An operation that can run is not necessarily one that can be inverted from its definition alone.

Use FluentMigration with BuildDown when the reverse needs its own steps. MigrationBuilder.WithReverse can attach an explicit backward operation to a forward operation. Dropping a newly created table on downgrade still destroys any data inserted since creation; automatic reversal is not data recovery.