Overview
What is C# EF Core Migrations By Example?
C# EF Core Migrations By Example is a code-first tutorial series teaching experienced .NET developers how to manage database schema evolution using Entity Framework Core Migrations. Through 30 heavily annotated, self-contained examples, you will achieve 95% coverage of EF Core migration patterns—from basic DbContext setup to idempotent script generation and production startup migrations.
This tutorial assumes you are an experienced developer familiar with C#, .NET, and relational databases. If you are new to C# or EF Core, start with foundational .NET tutorials first.
Why By Example?
Philosophy: Show the code first, run it second, understand through direct interaction.
Traditional tutorials explain concepts then show code. By-example tutorials reverse this: every example is a working, runnable code snippet with inline annotations showing exactly what happens at each step—migration class structure, generated SQL, CLI command output, and common pitfalls.
Target Audience: Experienced developers who:
- Already know C# and .NET fundamentals
- Understand relational databases and SQL
- Prefer learning through working code rather than narrative explanations
- Want comprehensive reference material covering 95% of production migration patterns
Not For: Developers new to C# or databases. This tutorial moves quickly and assumes foundational knowledge.
What Does 95% Coverage Mean?
95% coverage means the depth and breadth of EF Core migration features needed for production work, not toy examples.
Included in 95% Coverage
- DbContext Setup: DbContext class, DbSet properties, OnModelCreating configuration
- Migration Lifecycle: Creating, applying, reverting, and removing migrations
- MigrationBuilder Operations: CreateTable, AddColumn, DropColumn, CreateIndex, AddForeignKey
- CLI Tooling:
dotnet ef migrations add,dotnet ef database update,dotnet ef migrations list - History Tracking:
__EFMigrationsHistorytable, migration snapshot, Designer.cs metadata - Schema Constraints: Unique constraints, NOT NULL with defaults, CHECK constraints
- Column Types: UUID primary keys, timestamp columns, enum storage, precision types
- Relationships: Foreign keys, cascade delete, composite indexes, junction tables
- Seed Data: HasData seeding, idempotent data setup
- Advanced Operations: Column rename patterns, multiple tables per migration, SQL scripts
- Production Patterns: Idempotent scripts, ASP.NET Core startup migration application
Excluded from 95% (the remaining 5%)
- EF Core Internals: Provider adapter implementation, connection pool mechanics
- Rare Edge Cases: Obscure feature combinations not used in typical production code
- Database-Specific: Vendor-specific SQL fragments outside standard EF Core patterns
- Legacy Features: Deprecated APIs from EF Core 1.x or 2.x
- Custom Migration Operations: Writing custom IMigrationsSqlGenerator implementations
Tutorial Structure
30 Examples in One Beginner Level
Sequential numbering: Examples 1-30 (unified reference system)
Distribution:
- Beginner (Examples 1-30): 0-40% coverage — DbContext setup, migration basics, schema operations, CLI tooling, production patterns
Rationale: EF Core Migrations is a focused tool. Thirty examples provide granular progression from initial setup to production-ready SQL generation without overwhelming maintenance burden.
Five-Part Example Format
Every example follows a mandatory five-part structure:
Part 1: Brief Explanation (2-3 sentences)
Answers:
- What is this concept or pattern?
- Why does it matter in production code?
- When should you use it?
Part 2: Mermaid Diagram (when appropriate)
Included when (~40% of examples):
- Migration lifecycle has multiple stages
- Relationships between files need visualization
- CLI command flow is non-obvious
- Database schema relationships require illustration
Skipped when:
- Simple single-operation commands
- Straightforward column type changes
- Trivial additive migrations
Diagram requirements:
- Use color-blind friendly palette: Blue
#0173B2, Orange#DE8F05, Teal#029E73, Purple#CC78BC, Brown#CA9161 - Vertical orientation (mobile-first)
- Clear labels on all nodes and edges
- Comment syntax:
%%(NOT%%{ }%%)
Part 3: Heavily Annotated Code
Core requirement: Every significant line must have an inline comment.
Comment annotations use // => notation for C# and -- => for SQL:
migrationBuilder.CreateTable( // => Generates CREATE TABLE SQL statement
name: "users", // => Table name in the database
columns: table => new // => Lambda defines column set
{
id = table.Column<Guid>( // => Column named "id" of type uuid
type: "uuid", // => => Maps to PostgreSQL UUID type
nullable: false), // => => NOT NULL constraint applied
},
constraints: table => // => Lambda defines table-level constraints
{
table.PrimaryKey( // => Adds PRIMARY KEY constraint
"pk_users", x => x.id); // => => Constraint name and key column
});Required annotations:
- Migration builder calls: Document what SQL each method generates
- Column configurations: Show resulting SQL column definitions
- CLI commands: Show expected terminal output
- File paths: Note where generated files appear on disk
- Side effects: Document database changes, snapshot updates
Part 4: Key Takeaway (1-2 sentences)
Purpose: Distill the core insight to its essence.
Part 5: Why It Matters (50-100 words)
Purpose: Connect the pattern to real production consequences.
Self-Containment Rules
Critical requirement: Examples must be copy-paste-runnable within their chapter scope.
Beginner Level Self-Containment
Rule: Each example is completely standalone.
Requirements:
- Full class definitions with namespaces
- All necessary using statements
- Helper types defined in-place when needed
- No references to previous examples
- Runnable with
dotnet efCLI
Golden rule: If you delete all other examples, this example should still execute.
How to Use This Tutorial
Prerequisites
Before starting, ensure you have:
- .NET 8+ SDK installed
dotnet-efglobal tool installed (dotnet tool install --global dotnet-ef)- PostgreSQL (or your preferred database) running
- Basic C# and .NET knowledge
- Basic SQL and relational database knowledge
Running Examples
All CLI examples assume a project with EF Core configured:
# Install EF Core global tool
dotnet tool install --global dotnet-ef
# Create a migration
dotnet ef migrations add InitialCreate
# Apply migrations to database
dotnet ef database update
# Generate SQL script
dotnet ef migrations script --output migration.sqlLearning Path
For experienced .NET developers new to EF Core Migrations:
- Work through all 30 examples sequentially
- Run each CLI command in a test project
- Inspect generated migration files alongside examples
For quick reference:
- Use example numbers as reference (e.g., "See Example 9 for applying migrations")
- Search for specific patterns (Ctrl+F for "cascade", "unique", "HasData")
- Copy-paste examples as starting points for your migrations
Coverage Progression
- After Example 15 (40% coverage): Can create and apply basic migrations
- After Example 25 (70% coverage): Can handle most production schema operations
- After Example 30 (95% coverage): Expert-level EF Core migration mastery
Code Annotation Philosophy
Every example uses educational annotations to show exactly what happens:
// Migration class declaration
public partial class InitialCreate : Migration // => Partial class allows Designer.cs metadata
{
protected override void Up(MigrationBuilder migrationBuilder)
{ // => Up() runs on dotnet ef database update
migrationBuilder.CreateTable( // => Generates CREATE TABLE statement
name: "products", // => => Table name: products
columns: table => new // => => Column definitions
{
id = table.Column<int>( // => Column: id INTEGER
nullable: false), // => => NOT NULL constraint
});
}
}Annotations show:
- Generated SQL for each MigrationBuilder call
- CLI output from
dotnet efcommands - File system effects (files created, modified, or deleted)
- Database side effects (schema changes, constraint creation)
- Common pitfalls and edge cases
Quality Standards
Every example in this tutorial meets these standards:
- Self-contained: Copy-paste-runnable within chapter scope
- Annotated: Every significant line has an inline comment
- Tested: All code examples verified against real EF Core behavior
- Production-relevant: Real-world patterns, not toy examples
- Accessible: Color-blind friendly diagrams, clear structure
Next Steps
Ready to start? Begin with Beginner Examples (1-30).
Feedback and Contributions
Found an issue? Have a suggestion? This tutorial is part of the ayokoding-web learning platform. Check the repository for contribution guidelines.
Last updated March 26, 2026