Friday, 19 December 2025

Entity Framework core code first migration steps in detailed with example

 Below is a very detailed, step-by-step explanation of EF Core Code-First migrations with a complete real-time example, exactly how it’s expected in enterprise projects and interviews.


EF Core Code-First Migration – Detailed Steps with Example


What is Code-First in EF Core?

Code-First means:

  • You design C# entities first

  • EF Core generates the database schema

  • Migrations track schema changes over time

Database = output
C# code = source of truth


Real-Time Scenario

We are building a User Management API.

Initial Requirements

  • Create Users table

  • Later add Email, DateOfBirth, IsActive


Step 1: Create Web API Project

dotnet new webapi -n UserManagement.API
cd UserManagement.API

Step 2: Install Required Packages

dotnet add package Microsoft.EntityFrameworkCore
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Microsoft.EntityFrameworkCore.Tools

πŸ“Œ Tools is mandatory for migrations


Step 3: Create Entity Classes (Models)

πŸ“ Entities/User.cs

using System.ComponentModel.DataAnnotations;

public class User
{
    [Key]
    public int Id { get; set; }

    [Required]
    [MaxLength(100)]
    public string Name { get; set; }

    [MaxLength(200)]
    public string Email { get; set; }

    public DateTime DateOfBirth { get; set; }

    public bool IsActive { get; set; }
}

Step 4: Create DbContext

πŸ“ Data/AppDbContext.cs

using Microsoft.EntityFrameworkCore;

public class AppDbContext : DbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> options)
        : base(options)
    {
    }

    public DbSet<User> Users { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>()
            .Property(x => x.IsActive)
            .HasDefaultValue(true);
    }
}

Step 5: Configure Connection String

πŸ“ appsettings.json

"ConnectionStrings": {
  "DefaultConnection": "Server=.;Database=UserManagementDb;Trusted_Connection=True;TrustServerCertificate=True"
}

Step 6: Register DbContext (Program.cs)

builder.Services.AddDbContext<AppDbContext>(options =>
    options.UseSqlServer(
        builder.Configuration.GetConnectionString("DefaultConnection")));

Step 7: Add Initial Migration

dotnet ef migrations add InitialCreate

What EF Core Does

✔️ Scans entity classes
✔️ Compares model vs empty database
✔️ Generates migration files


Generated Migration (Simplified)

πŸ“ Migrations/xxxx_InitialCreate.cs

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>(maxLength: 100, nullable: false),
            Email = table.Column<string>(maxLength: 200, nullable: true),
            DateOfBirth = table.Column<DateTime>(nullable: false),
            IsActive = table.Column<bool>(nullable: false, defaultValue: true)
        },
        constraints: table =>
        {
            table.PrimaryKey("PK_Users", x => x.Id);
        });
}

Step 8: Apply Migration to Database

dotnet ef database update

✔️ Database created
✔️ Tables created
✔️ __EFMigrationsHistory table created


Step 9: Change Entity (New Business Requirement)

Add PhoneNumber field.

πŸ“ User.cs

[MaxLength(15)]
public string PhoneNumber { get; set; }

Step 10: Create New Migration

dotnet ef migrations add AddPhoneNumberToUser

Generated Migration

protected override void Up(MigrationBuilder migrationBuilder)
{
    migrationBuilder.AddColumn<string>(
        name: "PhoneNumber",
        table: "Users",
        maxLength: 15,
        nullable: true);
}

protected override void Down(MigrationBuilder migrationBuilder)
{
    migrationBuilder.DropColumn(
        name: "PhoneNumber",
        table: "Users");
}

Step 11: Update Database Again

dotnet ef database update

✔️ Schema updated
✔️ Existing data preserved


Step 12: Verify Database

Tables:

  • Users

  • __EFMigrationsHistory


Step 13: Rollback a Migration (If Needed)

dotnet ef database update InitialCreate

or

dotnet ef database update 0

Step 14: Remove Last Migration (Not Applied)

dotnet ef migrations remove

πŸ“Œ Only works if migration not applied


Step 15: Common EF Core Migration Commands

dotnet ef migrations list
dotnet ef migrations script
dotnet ef database update
dotnet ef migrations remove

Step 16: Data Seeding (Optional)

modelBuilder.Entity<User>().HasData(
    new User { Id = 1, Name = "Admin", Email = "admin@test.com", IsActive = true }
);

Then:

dotnet ef migrations add SeedUsers
dotnet ef database update

Real-Time Best Practices

✔️ One migration per feature
✔️ Never edit applied migrations
✔️ Avoid auto-migrate in production
✔️ Review generated SQL
✔️ Always keep migrations in Git


Common Interview Questions

Q: Difference between EnsureCreated() and migrations?
➡️ EnsureCreated() skips migrations – NOT for production

Q: Where migration history stored?
➡️ __EFMigrationsHistory


One-Line Interview Summary

EF Core Code-First migration allows developers to evolve database schema incrementally using C# models while maintaining version control and data safety.


If you want, I can next explain:

  • πŸ”₯ How EF Core tracks model changes internally

  • πŸ”₯ Multiple DbContext migrations

  • πŸ”₯ Zero-downtime production migrations

  • πŸ”₯ Handling breaking changes

  • πŸ”₯ EF Core migration interview Q&A

Just tell me πŸ‘



No comments:

Post a Comment

Recent Post

How to Migrate in EF Core Without Data Loss