Add Migration
Generate and apply EF Core migrations after model changes.
Read first: ~/.cursor/skills/webapp-shared/reference.md
When to use
- Entity properties added/removed/changed
- New
DbSet<>inAppDbContext - Fluent API configuration changes affecting schema
- After
add-entityoradd-featurebackend work
Prerequisites
- Model changes committed or staged in working tree
- App renamed from
AppName(use actual project names) -
dotnet-eftool available (host or api container)
Install tool if missing:
dotnet tool install -g dotnet-ef
# or: dotnet tool update -g dotnet-ef
Gather inputs
| Input | Example |
|---|---|
| Migration name | AddTodoItems |
| Environment | dev / prod |
| Apply now | yes (dev default) |
Use descriptive PascalCase migration names: Add{Entity}, Add{Entity}StatusIndex.
Checklist
Add-migration progress:
- [ ] 1. Verify model changes compile
- [ ] 2. Generate migration
- [ ] 3. Review generated migration file
- [ ] 4. Apply (dev) or plan apply (prod)
- [ ] 5. Verify schema / smoke test
Step 1: Build
cd backend
dotnet build
Fix compile errors before migrating.
Step 2: Add migration
Host SDK (preferred when available):
cd backend
dotnet ef migrations add <MigrationName> \
--project src/{App}.Infrastructure \
--startup-project src/{App}.Api \
--output-dir Persistence/Migrations
Via running api container:
docker compose exec api dotnet ef migrations add <MigrationName> \
--project src/{App}.Infrastructure \
--startup-project src/{App}.Api \
--output-dir Persistence/Migrations
Replace {App} with PascalCase app name (e.g. DemoApp).
Step 3: Review migration
Open backend/src/{App}.Infrastructure/Persistence/Migrations/*_<MigrationName>.cs:
- Expected tables/columns/indexes present
- No accidental drops of unrelated tables
- Destructive changes (column drops) flagged to user
If migration is wrong: dotnet ef migrations remove (same project flags) and fix model.
Step 4: Apply
Development
Option A — auto (default): Restart api; Program.cs runs MigrateAsync() when ASPNETCORE_ENVIRONMENT=Development:
docker compose restart api
docker compose logs api --tail 30 # confirm migrate applied
Option B — explicit:
cd backend
dotnet ef database update \
--project src/{App}.Infrastructure \
--startup-project src/{App}.Api
Production
Never rely on API startup migrate in Production.
During deploy (deploy-webapp), run once before or after bringing up api:
docker compose -f docker-compose.prod.yml --env-file .env.prod run --rm api \
dotnet ef database update \
--project src/{App}.Infrastructure \
--startup-project src/{App}.Api
Or equivalent one-off migrate job documented in template README.
Confirm ASPNETCORE_ENVIRONMENT=Production in .env.prod.
Step 5: Verify
# API health
curl -sf http://localhost:8080/api/health
# Exercise endpoint that uses new schema
docker compose exec db psql -U app -d {db_name} -c '\dt'
Run relevant tests: cd backend && dotnet test
Common issues
| Symptom | Fix |
|---|---|
Connection string missing |
Check .env / Compose env for ConnectionStrings__Default |
Build failed |
Fix model; migration not created |
Pending model changes |
New migration needed after further edits |
Jwt:SigningKey error on migrate |
Set key in .env even for migrate commands hitting startup project |
| Duplicate migration | Remove with dotnet ef migrations remove |
Do not
- Edit applied migration files in shared branches — add a new migration instead
- Enable auto-migrate in Production
- Skip reviewing generated SQL for destructive changes
Related skills
- Full feature with migration →
add-feature - Entity only →
add-entity - Prod apply context →
deploy-webapp - Local stack →
dev-webapp