8 minlesson

Migrations Overview

Migrations Overview

As your application evolves, your data model changes too. You add new entities, rename properties, change column types, and introduce relationships. EF Core migrations provide a structured way to apply these schema changes to your database without losing existing data.

Why Migrations?

Without migrations, you have two problematic options when your model changes:

  1. Drop and recreate the database every time, which destroys all existing data
  2. Hand-write ALTER TABLE scripts, which is error-prone and hard to track

EnsureCreated() is fine for prototyping, but it only creates a database if none exists. It cannot update an existing schema. If you add a property to an entity after the database already exists, EnsureCreated() will not add the new column.

csharp
1// This only creates the database if it doesn't exist
2// It CANNOT update an existing database schema
3await context.Database.EnsureCreatedAsync();

Migrations solve this by generating incremental change scripts that can be applied to an existing database.

What Is a Migration?

A migration is a C# class that describes a set of schema changes. Each migration has two methods:

  • Up - Applies the changes (e.g., create a table, add a column)
  • Down - Reverses the changes (e.g., drop the table, remove the column)

When you create a migration, EF Core compares your current model (C# entity classes) with a snapshot of the previous model and generates the difference.

1┌─────────────────────┐ ┌──────────────────────┐
2│ Previous Snapshot │ ──► │ Current C# Model │
3│ (stored in code) │ │ (your entity classes)│
4└─────────────────────┘ └──────────────────────┘
5 │ │
6 └─────────┐ ┌──────────────┘
7 ▼ ▼
8 ┌──────────────┐
9 │ Migration │
10 │ (Up / Down) │
11 └──────────────┘

The Migrations Folder

When you create your first migration, EF Core generates a Migrations folder in your project:

1MyProject/
2├── Migrations/
3│ ├── 20240115120000_InitialCreate.cs ← Migration code (Up/Down)
4│ ├── 20240115120000_InitialCreate.Designer.cs ← Snapshot at this point
5│ └── AppDbContextModelSnapshot.cs ← Current model snapshot
6├── Models/
7│ └── Product.cs
8├── AppDbContext.cs
9└── Program.cs

Migration File Naming

Each migration file is prefixed with a timestamp and includes the name you provide:

  • 20240115120000 - UTC timestamp (year, month, day, hour, minute, second)
  • InitialCreate - The name you gave the migration

The timestamp ensures migrations are ordered chronologically, which is important when applying them in sequence.

The Model Snapshot

The AppDbContextModelSnapshot.cs file stores the complete state of the model after all migrations have been applied. EF Core compares this snapshot with your current entity classes to determine what changed when you create a new migration.

You should never edit this file manually. EF Core maintains it automatically.

Migration Workflow

The typical workflow when changing your model is:

  1. Modify your entity classes (add properties, new entities, etc.)
  2. Create a migration to capture the changes
  3. Review the migration to verify it does what you expect
  4. Apply the migration to update the database

This cycle repeats every time you change your model:

Edit Model → Create Migration → Review → Apply → Repeat

Migrations vs EnsureCreated

It is important to understand when to use each approach:

FeatureEnsureCreatedMigrations
Creates databaseYesYes
Updates existing schemaNoYes
Tracks changes over timeNoYes
ReversibleNoYes (Down method)
Production-safeNoYes
Good for prototypingYesOverkill

Rule of thumb: Use EnsureCreated for quick prototypes and throwaway databases. Use migrations for anything that will persist or go to production.

Summary

In this lesson, you learned:

  • Migrations provide incremental, reversible schema changes for EF Core databases
  • Each migration has an Up method (apply) and a Down method (revert)
  • EF Core compares your current model against a stored snapshot to generate migrations
  • The Migrations folder contains migration files and a model snapshot
  • Migrations are essential for production applications; EnsureCreated is only for prototyping

Next, we will learn the specific CLI commands for creating, applying, and managing migrations.