Back to Dotnet Starter Kit

Create Migration

.agents/skills/create-migration/SKILL.md

10.0.02.7 KB
Original Source

Create Migration

All migrations live in one project — src/Host/FSH.Starter.Migrations.PostgreSQL — but are foldered per module/context (Catalog/, Identity/, …), each with its own {X}DbContextModelSnapshot. The DB is not migrated at API startup; the DbMigrator host applies it.

Step 0 — restore the pinned tool (first time)

bash
dotnet tool restore     # dotnet-ef is pinned in .config/dotnet-tools.json

Step 1 — BUILD FIRST (snapshot footgun)

dotnet ef migrations add reads the current snapshot, which is regenerated from a build. If you skip the build after editing entities/config, you can generate against a stale snapshot and lose changes. Also, migrations remove rewrites the snapshot — only remove the latest, and rebuild after.

bash
dotnet build src/FSH.Starter.slnx

Step 2 — add the migration

Specify all three of --project (the Migrations project), --startup-project (the API host), and --context {X}DbContext. Use --output-dir {X} so it lands in that module's folder (match the existing folder for the context).

bash
dotnet ef migrations add {MigrationName} \
  --project src/Host/FSH.Starter.Migrations.PostgreSQL \
  --startup-project src/Host/FSH.Starter.Api \
  --context {X}DbContext \
  --output-dir {X}

Step 3 — review the generated SQL before applying

bash
dotnet ef migrations script --idempotent \
  --project src/Host/FSH.Starter.Migrations.PostgreSQL \
  --startup-project src/Host/FSH.Starter.Api \
  --context {X}DbContext

Check for: unintended table/column drops, non-nullable columns added without a default to an existing table, and renames surfacing as drop+add (data loss). Adjust the model or hand-edit the migration if needed.

Step 4 — apply

Preferred (the canonical path — migrates the tenant catalog then each tenant's per-module schema):

bash
dotnet run --project src/Host/FSH.Starter.DbMigrator -- apply
dotnet run --project src/Host/FSH.Starter.DbMigrator -- list-pending   # to preview first

(Or, single-context local dev, dotnet ef database update --context {X}DbContext --project … --startup-project ….)

Notes

  • A new module also needs a {X}/ folder in the Migrations project and the runtime project referenced from it — see add-module.
  • dotnet ef against a BaseDbContext works because the 4-arg ctor is satisfied by the startup host's DI.

Checklist

  • dotnet tool restore done (first time)
  • Built before migrations add
  • --context {X}DbContext + --output-dir {X} (lands in the right folder)
  • Reviewed the generated SQL for data loss
  • Applied via DbMigrator apply (or ef database update for one context locally)