PANiXiDA.Core.Ef.Migrator
1.0.3
dotnet add package PANiXiDA.Core.Ef.Migrator --version 1.0.3
NuGet\Install-Package PANiXiDA.Core.Ef.Migrator -Version 1.0.3
<PackageReference Include="PANiXiDA.Core.Ef.Migrator" Version="1.0.3" />
<PackageVersion Include="PANiXiDA.Core.Ef.Migrator" Version="1.0.3" />
<PackageReference Include="PANiXiDA.Core.Ef.Migrator" />
paket add PANiXiDA.Core.Ef.Migrator --version 1.0.3
#r "nuget: PANiXiDA.Core.Ef.Migrator, 1.0.3"
#:package PANiXiDA.Core.Ef.Migrator@1.0.3
#addin nuget:?package=PANiXiDA.Core.Ef.Migrator&version=1.0.3
#tool nuget:?package=PANiXiDA.Core.Ef.Migrator&version=1.0.3
PANiXiDA.Core.Ef.Migrator
PANiXiDA.Core.Ef.Migrator is a .NET library for automatically creating and applying Entity Framework Core migrations when an application starts.
It is designed for services that use PostgreSQL with EF Core and need a controlled startup-time migration flow for development, test, or managed deployment scenarios.
Status
Overview
The package extends IHost with a migration startup step. It resolves the configured DbContext, detects pending model changes, optionally scaffolds a new EF Core migration into the target project, and optionally applies existing and generated migrations to PostgreSQL.
This package is intentionally small: build the host once and call RunMigrationsAsync<TContext>() for each DbContext that belongs to the service. Generation and application behavior is controlled through configuration.
Features
- Detects differences between the current
DbContextmodel and the latest model snapshot. - Generates migration files into a configured project directory.
- Applies compiled pending migrations.
- Applies a newly generated migration in the same startup flow.
- Processes multiple registered DbContexts sequentially without rebuilding the host.
- Supports disabling generation and applying independently.
- Uses PostgreSQL through
Npgsql.EntityFrameworkCore.PostgreSQL.
Quick Start
Requirements
- .NET 10 SDK
- Entity Framework Core 10
- PostgreSQL
Installation
<ItemGroup>
<PackageReference Include="PANiXiDA.Core.Ef.Migrator" Version="1.0.1" />
</ItemGroup>
Minimal import
using PANiXiDA.Core.Ef.Migrator;
First example
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Hosting;
using PANiXiDA.Core.Ef.Migrator;
using var host = Host
.CreateDefaultBuilder(args)
.ConfigureServices((context, services) =>
{
services.AddDbContext<AppDbContext>(options =>
{
options.UseNpgsql(
context.Configuration["PostgreSqlConnectionString"],
npgsql => npgsql.MigrationsAssembly(typeof(AppDbContext).Assembly.GetName().Name));
});
})
.Build();
await host.RunMigrationsAsync<AppDbContext>();
await host.RunAsync();
Multiple DbContexts
Register every module DbContext, build the host once, and migrate the contexts sequentially:
using var host = Host
.CreateDefaultBuilder(args)
.ConfigureServices((context, services) =>
{
var connectionString = context.Configuration["PostgreSqlConnectionString"];
services.AddDbContext<IdentityWriteDbContext>(options =>
{
options.UseNpgsql(
connectionString,
npgsql => npgsql.MigrationsAssembly(typeof(IdentityWriteDbContext).Assembly.GetName().Name));
});
services.AddDbContext<OrdersWriteDbContext>(options =>
{
options.UseNpgsql(
connectionString,
npgsql => npgsql.MigrationsAssembly(typeof(OrdersWriteDbContext).Assembly.GetName().Name));
});
})
.Build();
await host.RunMigrationsAsync<IdentityWriteDbContext>();
await host.RunMigrationsAsync<OrdersWriteDbContext>();
await host.RunAsync();
Each DbContext uses a configuration section named after its type:
{
"GenerateMigrations": true,
"ApplyMigrations": true,
"Ef": {
"Contexts": {
"IdentityWriteDbContext": {
"ProjectPath": "../Modules/Identity/Infrastructure",
"MigrationsDirectory": "Persistence/Migrations"
},
"OrdersWriteDbContext": {
"ProjectPath": "../Modules/Orders/Infrastructure",
"MigrationsDirectory": "Persistence/Migrations"
}
}
}
}
Each DbContext should also configure its own migrations history schema or table when the contexts share one database. This prevents different modules from sharing migration ownership accidentally.
For multiple independently deployed services, use the same pattern in each service's migrator host. Keeping migration execution with the owning service avoids coupling unrelated deployments.
Usage
Configuration
The migration flow is controlled by these configuration values:
| Key | Required | Default | Description |
|---|---|---|---|
GenerateMigrations |
No | true |
Enables creating a migration when the model differs from the latest snapshot. |
ApplyMigrations |
No | true |
Enables applying compiled pending migrations and the newly generated migration. |
Ef:Contexts:{DbContextName}:ProjectPath |
Yes, when generation is enabled and differences exist | None | Absolute or relative path to the project where migration files for the context should be written. |
Ef:Contexts:{DbContextName}:MigrationsDirectory |
Yes, when generation is enabled and differences exist | None | Migration output directory inside the context project path. |
Example appsettings.json:
{
"GenerateMigrations": true,
"ApplyMigrations": true,
"Ef": {
"Contexts": {
"AppDbContext": {
"ProjectPath": ".",
"MigrationsDirectory": "Data/Migrations"
}
}
},
"PostgreSqlConnectionString": "Host=localhost;Database=app;Username=app;Password=app"
}
Generate but do not apply
{
"GenerateMigrations": true,
"ApplyMigrations": false,
"Ef": {
"Contexts": {
"AppDbContext": {
"ProjectPath": ".",
"MigrationsDirectory": "Data/Migrations"
}
}
}
}
Apply existing migrations only
{
"GenerateMigrations": false,
"ApplyMigrations": true
}
Disable startup migrations
{
"GenerateMigrations": false,
"ApplyMigrations": false
}
Behavior Notes
- The caller builds the host once and invokes
RunMigrationsAsync<TContext>()for each context. - Each invocation creates an independent dependency injection scope.
- Multiple contexts are processed in the order in which the caller awaits them.
- A failure stops processing; migration application is not wrapped in a transaction spanning multiple DbContexts.
- When generation is disabled and applying is enabled, only compiled pending migrations are applied.
- When generation is enabled but there are no model differences, the package applies compiled migrations with EF Core
MigrateAsync()if applying is enabled. - When generation and applying are both disabled, the invocation completes without migration work.
- The generated migration ID is limited to 100 characters, including the timestamp prefix added by EF Core.
- Each context migrations directory must point to a directory inside its configured project path.
Project Structure
.
|-- src/
| `-- PANiXiDA.Core.Ef.Migrator/
|-- tests/
| `-- PANiXiDA.Core.Ef.Migrator.IntegrationTests/
|-- .github/
| `-- workflows/
| `-- ci.yml
|-- Directory.Build.props
|-- Directory.Build.targets
|-- Directory.Packages.props
|-- global.json
|-- version.json
|-- LICENSE
`-- README.md
Development
Build
dotnet restore
dotnet build --configuration Release
Format
dotnet format
Test
dotnet test --configuration Release
Integration tests use Testcontainers and require a working Docker environment.
Pack
dotnet pack --configuration Release
Full local validation
dotnet restore
dotnet format
dotnet build --configuration Release
dotnet test --configuration Release
dotnet pack --configuration Release
Tooling and Conventions
This repository uses:
- .NET 10
- Nullable enabled
- Implicit usings enabled
- Central package management
- Microsoft Testing Platform
- xUnit v3
- FluentAssertions
- Testcontainers for PostgreSQL integration tests
- Nerdbank.GitVersioning
- GitHub Actions
License
This project is licensed under the Apache-2.0 license.
See the LICENSE file for details.
Maintainers
Maintained by PANiXiDA.
For questions or improvements, use GitHub Issues or Pull Requests.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. 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. |
-
net10.0
- Microsoft.EntityFrameworkCore (>= 10.0.5)
- Microsoft.EntityFrameworkCore.Design (>= 10.0.5)
- Microsoft.Extensions.Configuration.Binder (>= 10.0.5)
- Microsoft.Extensions.Configuration.Json (>= 10.0.5)
- Microsoft.Extensions.Hosting (>= 10.0.5)
- Npgsql.EntityFrameworkCore.PostgreSQL (>= 10.0.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.