Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Execute Azure deployments using azd, Terraform, or Bicep with built-in error recovery.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/recipes/azd/ef-migrations.md
1# EF Core Migrations Deployment23Apply Entity Framework Core migrations to Azure SQL Database after deployment.45## Detection67EF Core projects contain `Migrations/` folder or `Microsoft.EntityFrameworkCore` package reference in `.csproj`.89```bash10find . -type d -name "Migrations" 2>/dev/null11find . -name "*.csproj" -exec grep -l "Microsoft.EntityFrameworkCore" {} \;12```1314**PowerShell:**15```powershell16Get-ChildItem -Recurse -Directory -Filter "Migrations" -ErrorAction SilentlyContinue17Get-ChildItem -Recurse -Filter "*.csproj" | Select-String -List "Microsoft.EntityFrameworkCore" | Select-Object -ExpandProperty Path18```1920## Deployment Methods2122### Method 1: azd Hook (Recommended)2324Automate via `postprovision` hook in `azure.yaml`:2526```yaml27hooks:28postprovision:29posix:30shell: sh31run: ./scripts/apply-migrations.sh32windows:33shell: pwsh34run: ./scripts/apply-migrations.ps135```3637**Copy the pre-built scripts** — Read [scripts/apply-migrations.sh](scripts/apply-migrations.sh) and [scripts/apply-migrations.ps1](scripts/apply-migrations.ps1) and write them verbatim to the project's `scripts/` folder. Adjust `APP_PROJECT_PATH` / `$AppProjectPath` in the script to the location of the `.csproj` directory.3839Key behaviours of the scripts:40- Loads `azd env get-values` safely (no `eval`)41- Installs `dotnet-ef` automatically when not present; no-op when already installed42- Fails on genuine install errors (network failure, missing SDK)43- Adds `~/.dotnet/tools` to `PATH` so the tool is immediately available4445> 💡 Make executable: `chmod +x scripts/*.sh`.4647### Method 2: SQL Script (Production)4849Generate idempotent script for review before applying:5051> ⚠️ **Warning:** `az sql db query` requires the `rdbms-connect` extension: `az extension add --name rdbms-connect --yes`5253```bash54dotnet ef migrations script --idempotent --output migrations.sql55az sql db query --server "$SQL_SERVER" --database "$SQL_DATABASE" \56--auth-mode ActiveDirectoryDefault --queries "$(cat migrations.sql)"57```5859**PowerShell:**60```powershell61dotnet ef migrations script --idempotent --output migrations.sql62$MigrationsSql = Get-Content migrations.sql -Raw63az sql db query --server $env:SQL_SERVER --database $env:SQL_DATABASE `64--auth-mode ActiveDirectoryDefault --queries $MigrationsSql65```6667### Method 3: Application Startup (Dev Only)6869⚠️ **Development only** — production should use explicit migration steps.7071```csharp72// Program.cs73if (app.Environment.IsDevelopment()) {74using var scope = app.Services.CreateScope();75scope.ServiceProvider.GetRequiredService<ApplicationDbContext>().Database.Migrate();76}77```7879## Combined Hook: SQL Access + Migrations8081Combine both steps in a single `postprovision` hook using the pre-built combined scripts:8283```yaml84hooks:85postprovision:86posix:87shell: sh88run: ./scripts/grant-and-migrate.sh89windows:90shell: pwsh91run: ./scripts/grant-and-migrate.ps192```9394**Copy the pre-built scripts** — Read [scripts/grant-and-migrate.sh](scripts/grant-and-migrate.sh) and [scripts/grant-and-migrate.ps1](scripts/grant-and-migrate.ps1) and write them verbatim to the project's `scripts/` folder. Adjust `APP_PROJECT_PATH` / `$AppProjectPath` in the script to the location of the `.csproj` directory.9596> 💡 Make executable: `chmod +x scripts/*.sh`9798## Prerequisites99100Install EF Core tools:101102```bash103dotnet tool install --global dotnet-ef104dotnet ef --version # Verify installation105```106107## Connection String108109```110Server=tcp:{server}.database.windows.net,1433;Database={database};Authentication=Active Directory Default;Encrypt=True;111```112113## Troubleshooting114115| Error | Solution |116|-------|----------|117| Cannot open database | Check firewall rules: `az sql server firewall-rule list` |118| Login failed | Grant SQL access per [sql-managed-identity.md](sql-managed-identity.md) |119| Unable to create DbContext | Add `IDesignTimeDbContextFactory` implementation |120| Hook fails but deployment continues | Remove `|| true` to make migrations block deployment |121122**DbContext Factory Example:**123124```csharp125public class ApplicationDbContextFactory : IDesignTimeDbContextFactory<ApplicationDbContext> {126public ApplicationDbContext CreateDbContext(string[] args) {127var optionsBuilder = new DbContextOptionsBuilder<ApplicationDbContext>();128var connectionString = Environment.GetEnvironmentVariable("CONNECTION_STRING")129?? args.FirstOrDefault() ?? "Server=(localdb)\\mssqllocaldb;Database=MyDb;Trusted_Connection=True;";130optionsBuilder.UseSqlServer(connectionString);131return new ApplicationDbContext(optionsBuilder.Options);132}133}134```135136## Best Practices137138- Use `--idempotent` flag for production scripts139- Version control Migrations/ folder140- Test locally before deploying141- Backup production databases before applying142- Keep migrations small and focused143144## References145146- [SQL Managed Identity Access](sql-managed-identity.md)147- [Post-Deployment Guide](post-deployment.md)148- [EF Core Migrations](https://learn.microsoft.com/ef/core/managing-schemas/migrations/)149