EF Core Migrations
Version control for your database schema with Entity Framework Core.
A Simple Analogy
Migrations are like version control for databases. Each change creates a new version file, you can move forward or backward in time, and team members sync the same schema.
Why Migrations?
- Version control: Track all schema changes in Git
- Team coordination: Everyone applies same changes
- Production deployment: Reliable schema updates
- Rollback capability: Undo changes if needed
- Documentation: Migration history explains why
Create Migration
// Define entities
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
public class AppDbContext : DbContext
{
public DbSet<User> Users { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("connection-string");
}
}
// Create migration
// dotnet ef migrations add InitialCreate
// Migration file generated automatically:
// Migrations/20250220120000_InitialCreate.cs
Migration Structure
public partial class InitialCreate : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Users",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Name = table.Column<string>(nullable: false),
Email = table.Column<string>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Users", x => x.Id);
});
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(name: "Users");
}
}
Applying Migrations
// In Program.cs
var app = builder.Build();
// Auto-apply migrations on startup
using (var scope = app.Services.CreateScope())
{
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
db.Database.Migrate(); // Applies all pending migrations
}
app.Run();
# Manual application
dotnet ef database update
# Apply specific migration
dotnet ef database update InitialCreate
# Rollback to previous
dotnet ef database update PreviousMigration
# List migrations
dotnet ef migrations list
Adding Columns
// Add column to entity
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public DateTime CreatedAt { get; set; } // NEW
}
// Create migration
// dotnet ef migrations add AddCreatedAtToUsers
// Generated migration:
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<DateTime>(
name: "CreatedAt",
table: "Users",
nullable: false,
defaultValue: DateTime.UtcNow);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn("CreatedAt", "Users");
}
Complex Migrations
public partial class SplitNameColumn : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
// Add new columns
migrationBuilder.AddColumn<string>(
name: "FirstName",
table: "Users",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "LastName",
table: "Users",
nullable: true);
// SQL to split existing name
migrationBuilder.Sql(
@"UPDATE Users SET FirstName = SUBSTRING(Name, 1, CHARINDEX(' ', Name)-1),
LastName = SUBSTRING(Name, CHARINDEX(' ', Name)+1, LEN(Name))");
// Make new columns non-nullable
migrationBuilder.AlterColumn<string>(
name: "FirstName",
table: "Users",
nullable: false);
migrationBuilder.AlterColumn<string>(
name: "LastName",
table: "Users",
nullable: false);
// Drop old column
migrationBuilder.DropColumn("Name", "Users");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
// Reverse operations...
}
}
Best Practices
- Create frequently: One feature = one migration
- Name descriptively:
AddUserRoleColumn, notMigration2 - Keep idempotent: Safe to run multiple times
- Test rollbacks: Verify Down() works
- Review generated code: Ensure correctness
Related Concepts
- Database snapshots
- Initial data seeding
- Shadow properties
- Fluent API configuration
Summary
EF Core Migrations provide version control for database schemas. Master creating, applying, and rolling back migrations to maintain consistency across development and production environments.
Related Articles
EF Core JSON Columns
Store and query JSON data with Entity Framework Core.
Read More databaseAzure Cosmos DB with ASP.NET Core
Build globally distributed applications with Azure Cosmos DB.
Read More databaseEF Core Performance Optimization
Optimize Entity Framework Core queries for maximum performance.
Read More