100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
C#

Migrations Fundamentals

Learn how EF Core migrations track model changes and generate versioned database schema updates while preserving existing data.

MigrationsBeginner8 min readJul 10, 2026
Analogies

What Are EF Core Migrations?

EF Core migrations are a way to incrementally update a database schema to keep it in sync with your application's data model while preserving existing data. When you run dotnet ef migrations add <Name>, EF Core compares your current model against a stored snapshot of the last known model state (the ModelSnapshot class) and generates a migration file containing exactly the operations needed to move the schema from one state to the next, rather than rebuilding the database from scratch.

🏏

Cricket analogy: Think of a scorer's ledger during a Test match — each migration is like adding a new page recording only what changed since the last session break (a new batsman in, a wicket fallen), rather than rewriting the entire scorecard from ball one.

Anatomy of a Migration File

Each migration class inherits from Migration and implements two methods: Up(), which applies the schema change using MigrationBuilder calls like CreateTable or AddColumn, and Down(), which reverses it. EF Core decorates the class with a [Migration] attribute carrying a timestamp-prefixed ID (for example 20260710120000_AddOrdersTable) so migrations apply in a deterministic order, and it regenerates the ModelSnapshot file so future migrations add calls diff against the correct baseline.

🏏

Cricket analogy: It's like an umpire's official match report having two sections — one recording the day's play (Up) and one that could, in theory, annul it (Down) — each timestamped so the sequence of a five-day Test is unambiguous.

csharp
public partial class AddOrdersTable : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.CreateTable(
            name: "Orders",
            columns: table => new
            {
                Id = table.Column<int>(nullable: false)
                    .Annotation("SqlServer:Identity", "1, 1"),
                CustomerId = table.Column<int>(nullable: false),
                PlacedOn = table.Column<DateTime>(nullable: false)
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_Orders", x => x.Id);
            });
    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DropTable(name: "Orders");
    }
}

The Model Snapshot and Change Detection

The ModelSnapshot class is a full, self-contained serialization of your EF Core model as of the last migration, committed to source control alongside migration files. When you run migrations add, EF Core's internal model differ compares the current DbContext model — derived from your entity classes, data annotations, and Fluent API configuration — against this snapshot to compute the precise set of operations needed. Critically, this comparison happens against the snapshot, not against the live database.

🏏

Cricket analogy: It's like comparing this season's official squad list against last season's, not against who actually turned up to nets — if a player was quietly swapped without updating the official list, the comparison won't catch it.

Because migrations diff against the ModelSnapshot rather than the live database, any manual schema change made outside of migrations (a column added directly in SSMS, for example) will not be detected automatically — this is the root cause of the schema drift problems covered in the 'Handling Schema Drift in Teams' topic.

  • Migrations incrementally evolve the database schema while preserving existing data, rather than recreating the database.
  • dotnet ef migrations add <Name> diffs the current model against the ModelSnapshot, not the live database.
  • Each migration implements Up() to apply changes and Down() to reverse them.
  • Migration classes are timestamp-prefixed so they apply in a deterministic, ordered sequence.
  • The ModelSnapshot.cs file is a full serialization of the model and must be committed to source control.
  • Because comparisons are snapshot-based, out-of-band manual database changes are invisible to EF Core until they cause a failure.

Practice what you learned

Was this page helpful?

Topics covered

#EntityFrameworkCoreStudyNotes#MicrosoftTechnologies#MigrationsFundamentals#Migrations#Fundamentals#Core#Anatomy#StudyNotes#SkillVeris#ExamPrep