Chd.Library.Migrations 8.6.4

dotnet add package Chd.Library.Migrations --version 8.6.4
                    
NuGet\Install-Package Chd.Library.Migrations -Version 8.6.4
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Chd.Library.Migrations" Version="8.6.4" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Chd.Library.Migrations" Version="8.6.4" />
                    
Directory.Packages.props
<PackageReference Include="Chd.Library.Migrations" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Chd.Library.Migrations --version 8.6.4
                    
#r "nuget: Chd.Library.Migrations, 8.6.4"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Chd.Library.Migrations@8.6.4
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Chd.Library.Migrations&version=8.6.4
                    
Install as a Cake Addin
#tool nuget:?package=Chd.Library.Migrations&version=8.6.4
                    
Install as a Cake Tool

Migration Library for .NET Core

NuGet License


📝 Table of Contents


About

Chd.Library.Migration is a production-ready, attribute-based, fluent database migration library for .NET Core.
Manage schema and data versioning for PostgreSQL, Oracle, MsSQL, and SQLite using clean C# and a proven migration approach.
No more SQL scripts or CLI headaches—get full control, auditability, and speed in all environments.


Features

  • Attribute-based versioned migrations: [Migration(version, author)]
  • Powerful fluent DSL for all schema/data operations: Create, Alter, Drop, Insert, Update, Delete, Index, Constraints, Execute SQL, and more.
  • Auto-discovers all migration classes in your project (no manual registration)
  • Runs all pending migrations automatically at app startup, in a background thread for speed and safety
  • Tracks migration history using a dedicated VersionInfo table
  • Supports both startup and on-demand migration triggers
  • Fully thread-safe, standardized and production tested
  • .NET 9.0+ support

Quick Start

  1. Install:

    dotnet add package Chd.Library.Migration
    
  2. Configure your connection strings:

    "ConnectionStrings": {
      "PostgreSQLTest": "Host=localhost;Port=5432;Database=my_db;User ID=postgres;Password=xxx;",
      "OracleTest":"Data Source=...;User Id=...;Password=...;",
      "MsSQLTest": "Server=...;Database=...;User Id=...;Password=...;",
      "SQLiteTest": "Data Source=mydb.db;"
    }
    
  3. Register your migration(s) in DI (choose the database you use):

    // In Program.cs
    builder.Services.AddMigration<Program>(DatabaseType.PostgreSQL, "PostgreSQLTest");
    

🚦 How Migrations Are Applied

  • Automatic & Threaded:
    On application startup, all pending migrations are executed in a background thread—keeping startup blazing-fast and never blocking the API/UI.
  • On-demand, anywhere:
    Trigger migrations anytime with DatabaseMigration.RunMigration<T>(...) (CLI tools, admin panels, deployment hooks, etc.).
  • Single Source of Truth:
    The VersionInfo table records migration versioning and prevents accidental or duplicate runs—ensuring safety across all environments.
  • Production-Proven:
    Battle-tested in multiple enterprise, microservice, and critical app deployments.

Database Integration (DI)

PostgreSQL

builder.Services.AddMigration<Program>(DatabaseType.PostgreSQL, "PostgreSQLTest");

Oracle

builder.Services.AddMigration<Program>(DatabaseType.Oracle, "OracleTest");

MsSQL

builder.Services.AddMigration<Program>(DatabaseType.MsSQL, "MsSQLTest");

SQLite

builder.Services.AddMigration<Program>(DatabaseType.SQLite, "SQLiteTest");

On-demand Migration

DatabaseMigration.RunMigration<Program>(DatabaseType.PostgreSQL, "YourFullConnectionStringHere");

(Runs migrations on demand, in a background thread.)


Configuration

Set your databases in appsettings.json (or any .NET config provider):

"ConnectionStrings": {
  "PostgreSQLTest": "Host=localhost;Port=5432;Database=my_db;User ID=postgres;Password=xxx;",
  "OracleTest": "Data Source=...;User Id=...;Password=...;",
  "MsSQLTest": "Server=...;Database=...;User Id=...;Password=...;",
  "SQLiteTest": "Data Source=mydb.db;"
}

Writing Migrations

Schema Migration Example

[Migration(1, "Mehmet Yoldaş")]
public class StudentTableMigration : Migration
{
    public override void Up()
    {
        Create.Table("student")
            .WithIdColumn()
            .WithColumn("first_name").AsString().NotNullable()
            .WithColumn("last_name").AsString(255)
            .WithColumn("user_name").AsString()
            .WithColumn("birth_date").AsDate().Nullable();
    }
    public override void Down()
    {
        Delete.Table("student");
    }
}

Creates a table with primary key and string/date columns. Down() removes it.


Data Migration Example

[Migration(1000001, "Mehmet Yoldaş")]
public class SeedStudents : Migration
{
    public override void Up()
    {
        Insert.Into("student").Row(new { first_name = "Mehmet", last_name = "Yoldaş", user_name = "mehmetyoldas", birth_date = DateTime.Now });
        Insert.Into("student").Row(new { first_name = "Ali", last_name = "Yılmaz", user_name = "aliyilmaz", birth_date = DateTime.Now });
    }
    public override void Down()
    {
        // Remove seeded data if possible
    }
}

Inserts several rows; Down() can delete or ignore as needed.


Comprehensive Fluent Migration Reference

Below is a reference of the most common migration operations—with short explanations.

CREATE TABLE

Create.Table("users")
    .WithIdColumn()
    .WithColumn("name").AsString().NotNullable()
    .WithColumn("email").AsString(255).Unique()
    .WithColumn("created_at").AsDateTime().WithDefault(DateTime.UtcNow);

Create a table, use different column types, unique constraint, and default value.


ALTER TABLE (ADD COLUMN)

Alter.Table("users").AddColumn("is_active").AsBoolean().WithDefault(true);

Add a boolean column with default.


INSERT DATA

Insert.Into("users").Row(new { name = "Jane", email = "jane@site.com", created_at = DateTime.UtcNow });

Insert a row into a table.


UPDATE DATA

Update.Table("users").Set(new { email = "jane@newmail.com" }).Where(new { name = "Jane" });

Update matching rows using an anonymous object as WHERE filter.


DELETE DATA

Delete.From("users").Row(new { name = "Jane" });

Delete a row with matching field(s).


DROP COLUMN

Delete.Column("is_active").FromTable("users");

Remove a column.


CREATE INDEX

Create.Index("ix_users_email")
    .OnTable("users")
    .OnColumn("email")
    .Ascending()
    .Unique();

Index definition—ascending, unique.


ADD FOREIGN KEY

Create.ForeignKey("fk_orders_user")
    .FromTable("orders").ForeignColumn("user_id")
    .ToTable("users").PrimaryColumn("id")
    .OnDelete(System.Data.Rule.Cascade);

Create a foreign key with cascade.


EXECUTE RAW SQL

Execute.Sql("UPDATE users SET is_active = 1 WHERE is_active IS NULL");

Direct SQL execution for advanced or data-fix scenarios.


RENAME TABLE / COLUMN

Rename.Table("old_users").To("users");
Rename.Column("surname").OnTable("users").To("last_name");

Rename any table or column.


Advanced Usage & Best Practices

  • Don’t forget Down() methods: Guarantee safe rollbacks in migrations, especially for destructive ops.
  • Versioning Strategy: Use ascending integer versions; recommend < 1,000,000 for schema, ≥ 1,000,000 for data.
  • Chained/Multi-table migrations: You can create highly complex migration sequences, chained Up()/Down()’s for transactional/atomic deployment strategies.
  • CI/CD Ready: Migrations are designed for hands-off automation—works perfectly in scalable, cloud-native environments.

Production Tips & Troubleshooting

  • Migration not running?
    • Confirm [Migration] attribute & base class; check namespace is discoverable.
    • Ensure you call the correct AddMigration<T> root class in DI.
  • Migration errors:
    • Fix the migration, re-deploy—system will retry safely. Check the VersionInfo table for current state.
  • Order and atomicity:
    • Always version and order migrations strictly! Never modify applied migrations—append new ones only for any fix.
  • Failure Recovery:
    • Well-written Down() enables you to revert migrations if you ever need emergency rollback.

FAQ

Q: Can I use the same library for multiple databases?
Yes, register each DB via AddMigration<T>(DatabaseType, ConnectionStringKey) in DI. Each keeps its own migration chain.

Q: I want to trigger migrations from an admin panel or after deployment.
Just use the On-Demand API:

DatabaseMigration.RunMigration<Program>(DatabaseType.MsSQL, "connectionstring");

Q: Is it safe for production, CI/CD, and cloud?
Absolutely! This system is running in high-availability production SaaS, web, and microservice environments.

Q: Can I write fully custom SQL if needed?
Yes—use the Execute.Sql(...) method for any edge-case, batch, or one-off data fix.


Feature Comparison

Feature Chd.Library.Migration FluentMigrator EF Core Migrations Flyway (Java)
Attribute Versioning
Fluent C# DSL Limited
Multi-Database Partial
On-Demand Trigger Partial
DI Integration Partial
Battle-Tested

Authors

See also contributors on NuGet


Acknowledgements

  • Inspired by FluentMigrator, EF, and Flyway
  • Special thanks to organizations and engineers who have tested and improved this library in critical production environments

For issues, feature requests or pull requests, visit mehmet-yoldas/library-core

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
8.6.4 94 1/20/2026
8.6.3 87 1/17/2026
8.6.2 91 1/15/2026
8.6.1 92 1/12/2026
8.6.0 95 1/12/2026
8.5.9 279 12/23/2025
8.5.8 151 12/20/2025
8.5.7 248 12/19/2025
8.5.6 244 12/19/2025
8.5.4 250 8/17/2025
8.5.3 447 8/3/2025
8.5.2 184 7/31/2025
8.5.1 601 7/23/2025
8.0.9 201 12/23/2024
8.0.8 188 12/23/2024
8.0.3 497 2/3/2024
8.0.2 456 2/3/2024
8.0.1 486 2/3/2024
8.0.0 473 1/30/2024
7.4.5 625 9/4/2023
7.4.4 581 9/4/2023
7.4.3 619 9/4/2023
7.4.2 692 9/4/2023
7.4.1 689 8/25/2023
7.4.0 678 8/18/2023
7.3.3 852 8/9/2023
1.3.3 842 5/28/2023
1.3.2 763 5/11/2023
1.3.1 817 4/28/2023
1.3.0 852 4/28/2023
1.2.9 898 4/24/2023
1.2.8 787 4/20/2023
1.2.7 1,084 1/30/2023
1.1.9 2,821 1/30/2023