Skip to main content

Command Palette

Search for a command to run...

Entity Framework Core - Deployment Strategies overview

Published
โ€ข3 min read

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.

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 .exe to our server (or Docker container) and run it. It checks the database and applies only pending migrations.

  • Command: dotnet ef migrations bundle

  • Pros: 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 --idempotent

  • Pros: The --idempotent flag 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 .dacpac file.

  • Deployment: We use a tool like SqlPackage.exe to 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.