Migrations
Level: Beginner
ℹ️ Where This Fits
Migrations track schema changes over time. This enables version control of your database, enabling teams to collaborate and deploy safely.
ℹ️ What You'll Learn
- Migration purpose: Track database schema changes as code (version control friendly)
- Workflow: Modify entity → add migration → review SQL → update database
- dotnet ef migrations add: Create new migration file based on model changes
- dotnet ef database update: Apply pending migrations to database
- Automatic timestamping: Migration files timestamped (202401151430_AddStudentTable.cs)
- Up method: SQL to apply migration (ALTER TABLE, CREATE TABLE, etc)
- Down method: SQL to revert migration (rollback)
- Migration history: __EFMigrationsHistory table tracks applied migrations
- Idempotent scripts: Migrations check if already applied (safe to re-run)
- Removing migrations: dotnet ef migrations remove (only before applying)
- Script-only: dotnet ef migrations script (generates SQL without applying)
- School Management migrations: Initial, AddStudentTable, AddExamResults, AddFeePayments
- Common mistakes: Modifying migration files manually, removing applied migrations, losing down methods
Basic Migration Workflow
# 1. Create migration (generates SQL based on model changes)
dotnet ef migrations add InitialCreate
# 2. Apply migration to database
dotnet ef database update
# 3. View generated SQL (without applying)
dotnet ef migrations script
Migration File Example
Generated file: Migrations/20240115143045_InitialCreate.cs
public partial class InitialCreate : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Students",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Name = table.Column<string>(maxLength: 100, nullable: false),
ClassName = table.Column<string>(maxLength: 10, nullable: false),
RollNumber = table.Column<string>(maxLength: 20, nullable: false),
DateOfBirth = table.Column<DateTime>(nullable: false),
Status = table.Column<int>(nullable: false),
CreatedAt = table.Column<DateTime>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Students", x => x.Id);
});
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(name: "Students");
}
}
Adding Foreign Key Migration
dotnet ef migrations add AddExamToStudent
Generated SQL:
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Exams",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
ExamName = table.Column<string>(maxLength: 100, nullable: false),
SubjectId = table.Column<int>(nullable: false),
ExamDate = table.Column<DateTime>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Exams", x => x.Id);
table.ForeignKey(
name: "FK_Exams_Subjects_SubjectId",
column: x => x.SubjectId,
principalTable: "Subjects",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
}
Updating Existing Migration (Before Apply)
If migration not yet applied:
# Remove the migration (before update)
dotnet ef migrations remove
# Modify your entities
# Create new migration
dotnet ef migrations add FixedMigrationName
# Apply
dotnet ef database update
Reverting Applied Migrations
Revert to previous migration:
# List migrations
dotnet ef migrations list
# Revert to specific migration (this runs Down method)
dotnet ef database update PreviousMigration
Generate SQL Script (Without Applying)
# Generate SQL to file
dotnet ef migrations script > migrations.sql
# Generate SQL from specific migration range
dotnet ef migrations script AddStudents AddFees > fee-migrations.sql
Best Practices
✓ Always review generated migrations before applying ✓ Never modify applied migrations (create new one instead) ✓ Use descriptive migration names ✓ Commit migrations to git ✓ Apply migrations in order
💡 Safe Schema Changes
For production:
- Run migration in staging first
- Review generated SQL
- Backup database before applying
- Apply with rollback plan ready
🤖Use AI to Learn Faster
Use ChatGPT, Claude, or Copilot to go deeper on Migrations. Try these prompts:
"What's the difference between 'add migration' and 'update database'?""How do you revert a migration that was already applied?""Why should you review the generated SQL before applying?""What's stored in the __EFMigrationsHistory table?"
💡 Tip: After reading this article, paste your own code into AI and ask "What could go wrong here and why?" — fastest way to find edge cases and deepen understanding.
Next Article
nexcoding.in
Have questions on your tech stack, ongoing projects, or need one-to-one training?