For various reasons (legacy db) we often have an already existing database where we want to level up our database migration process.

The way we handle migrations in Entity Framework Core (EF Core) is to use their CLI tools.

It's important to make sure that cmd / powershell points to the correct directory. In this sample we use "C:\MyProject\".

First we have to add the following package reference.

<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.0">
  <!-- ๐Ÿ‘‡๐Ÿ‘‡๐Ÿ‘‡ Remove this line when using a different assembly (see below) -->
  <!-- <PrivateAssets>all</PrivateAssets> -->
  <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

1) Lets start with our initial migration. This will generate a Migrations folder "C:\MyProject\WebApp\Migrations\" and also a table in our database called "__EFMigrationsHistory".

C:\MyProject\WebApp> dotnet ef migrations add Initial

2) Open the generated "20221109165679_Initial.cs" and remove the method body of Up() + Down().

public partial class Initial : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        // Leave empty
    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {
        // Leave empty
    }
}

3) Update the database with our inital migration.

C:\MyProject\WebApp> dotnet ef database update

Because we removed the body of the Up() method, this command will accordingly do nothing except insert a row into "__EFMigrationsHistory" that this migration is done.

4) Finished! Now we can start making changes to our model and start at 1) again. Just skip 2) ๐Ÿ˜Š

EF Core migrations with different assembly

We have to change our migration command.

C:\MyProject\> dotnet ef migrations add Initial --project Infrastructure --startup WebApp

Apply migrations at application startup

Alternative to 3) we can apply migrations in our Program.cs (top-level Minimal API startup).

var builder = WebApplication.CreateBuilder(args);

// Register services

var app = builder.Build();

// Register middlewares

var dbContext = app.Services.GetRequiredService<ApplicationDbContext>();
await dbContext.Database.MigrateAsync();

await app.RunAsync();

Apply migrations manually

Another alternative to apply migrations is to generate the migration SQL. This has the advantage to review the generated SQL before applying it to a production database.

C:\MyProject\WebApp> dotnet ef migrations script