Entity Framework Core - Deployment Strategies overview
When working with Entity Framework Core, deploying database changes is a critical step in the CI/CD pipeline. The strategy depends heavily on whether we are using a Code-First (C# defines the DB) or Database-First (DB defines the C#) approach.
Here is a comprehensive list of all deployment strategies.
Part 1: Code-First Approaches
In this approach, our C# migrations are the source of truth.
1. Migration Bundles (Recommended ๐)
Introduced in EF Core 6, this is the modern gold standard for DevOps pipelines.
How it works: We compile our migrations into a single, self-contained executable file (e.g.,
efbundle.exe).Deployment: We copy this
.exeto our server (or Docker container) and run it. It checks the database and applies only pending migrations.Command:
dotnet ef migrations bundlePros: No SDK required on the server; easy to integrate into GitHub Actions/Azure DevOps.
2. SQL Script Generation (Idempotent Scripts)
This is the safest enterprise approach. We generate a raw .sql file that represents the changes.
How it works: We ask EF Core to generate a script that converts the database from "Migration A" to "Migration B".
Deployment: A DBA reviews the script, or a tool (like
sqlcmd) runs it against the production database.Command:
dotnet ef migrations script --idempotentPros: The
--idempotentflag ensures the script checks if a migration has already been applied before running, preventing errors. DBAs love this because they can see exactly what will happen.
3. Application Startup (Database.Migrate())
This is the "Lazy" approach. We put code in our Program.cs that runs migrations every time the app starts.
How it works:
using (var scope = app.Services.CreateScope()) { var db = scope.ServiceProvider.GetRequiredService<AppDbContext>(); db.Database.Migrate(); }Pros: extremely easy; zero deployment configuration needed.
Cons (Critical):
Concurrency: If we scale our app to 2+ instances, multiple apps will try to upgrade the database simultaneously, causing race conditions and crashes.
Security: Our running application requires "DDL Admin" (schema modification) permissions, which violates the Principle of Least Privilege.
Part 2: Database-First Approaches
In this approach, the SQL database is the source of truth, and we usually reverse-engineer our C# classes (Scaffold-DbContext).
1. SQL Server Data Tools (DACPAC) ๐
If we are using SQL Server, this is the industry standard.
How it works: We maintain a "Database Project" (
.sqlproj) in Visual Studio that mirrors our schema. When we build it, it creates a.dacpacfile.Deployment: We use a tool like
SqlPackage.exeto compare the.dacpac(our desired state) against the target database (current state). It automatically generates and runs the "diff" script.Pros: Handles complex scenarios (stored procs, views, permissions) much better than EF Core migrations.

