C# Template – Migration

A Laravel-inspired migration builder for C# WinForms using MySQL. It provides a fluent, intuitive way to manage your database schema through code using MigrationBase, TableBuilder, and ColumnBuilder.

Base Class: BaseMigration

All migrations should inherit from MigrationBase, which defines the structure and tools needed for schema operations.

public abstract class BaseMigration
{
    public abstract string Name { get; } // Unique name of the migration (timestamp-based recommended)
    public abstract void Up(); // Defines what to do when applying the migration
    public abstract void Down(); // Defines what to do when rolling back the migration

    protected void RunSql(string sql); // Execute raw SQL
    protected void DropTable(string tableName); // Drop table if exists
    protected void CreateTable(string tableName, Action<TableBuilder> build); // Create table using a builder
}

TableBuilder Usage

Used inside CreateTable() to fluently define columns:

Example:

CreateTable("users", table =>
{
    table.Int("id").PrimaryKey().AutoIncrement();
    table.String("username", 100).Unique();
    table.String("email", 255).Default("[email protected]");
    table.Timestamp("created_at");
});

Available Column Types:

Type MethodDescription
Int(name, len)Integer column
String(name, len)VARCHAR column
Timestamp(name)TIMESTAMP column
Boolean(name)TINYINT(1) for true/false values
Date(name)Date column
DateTime(name)DateTime column
Decimal(name, len)Decimal column

ColumnBuilder Chainable Methods

Each column can be configured using these methods:

MethodDescription
PrimaryKey()Sets column as the primary key
AutoIncrement()Auto-increment integer
Unique()Adds a UNIQUE constraint
Default(value)Sets a default value for the column

Creating a Migration

Step 1: Create a Migration Class

public class CreateUsersTable : BaseMigration
{
    public override string Name => "20250722_create_users_table";
   string tableName = "users";
     
    public override void Up()
    {
        CreateTable(tableName, table =>
        {
            table.Int("id").PrimaryKey().AutoIncrement();
            table.String("username", 100).Unique();
            table.String("email", 255).Default("[email protected]");
            table.Timestamp("created_at");
        });
    }

    public override void Down()
    {
        DropTable(tableName);
    }
}

Step 2: Run Migration

You can manage migrations via your custom migration runner. Here’s an example that runs during LoginForm_Load() and only fires if it’s fired using F5 from Visual Studio:

bool isRunningUnderDebugger = Debugger.IsAttached;
if (isRunningUnderDebugger)
{
    //MigrationManager.RollbackLastMigration();
    MigrationManager.RunMigrations();
}

Best Practices

  • Use a timestamp-based Name for uniqueness (example 20250722_create_users_table).
  • Keep migrations idempotent and simple.
  • Always provide a Down() method for rollback capability.
  • Store applied migration names in a __migrations table (your system should handle this).