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:
- Drop and recreate the database every time, which destroys all existing data
- 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.
csharp1// This only creates the database if it doesn't exist2// It CANNOT update an existing database schema3await 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 point5│ └── AppDbContextModelSnapshot.cs ← Current model snapshot6├── Models/7│ └── Product.cs8├── AppDbContext.cs9└── 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:
- Modify your entity classes (add properties, new entities, etc.)
- Create a migration to capture the changes
- Review the migration to verify it does what you expect
- 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:
| Feature | EnsureCreated | Migrations |
|---|---|---|
| Creates database | Yes | Yes |
| Updates existing schema | No | Yes |
| Tracks changes over time | No | Yes |
| Reversible | No | Yes (Down method) |
| Production-safe | No | Yes |
| Good for prototyping | Yes | Overkill |
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
Upmethod (apply) and aDownmethod (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;
EnsureCreatedis only for prototyping
Next, we will learn the specific CLI commands for creating, applying, and managing migrations.