Smithery Logo
MCPsSkillsDocsPricing
Login
Smithery Logo

Accelerating the Agent Economy

Resources

DocumentationPrivacy PolicySystem Status

Company

PricingAboutBlog

Connect

© 2026 Smithery. All rights reserved.

    onesmartguy

    dotnet-ef-migrations

    onesmartguy/dotnet-ef-migrations
    Coding
    2

    About

    SKILL.md

    Install

    Install via Skills CLI

    or add to your agent
    • Claude Code
      Claude Code
    • Codex
      Codex
    • OpenClaw
      OpenClaw
    • Cursor
      Cursor
    • Amp
      Amp
    • GitHub Copilot
      GitHub Copilot
    • Gemini CLI
      Gemini CLI
    • Kilo Code
      Kilo Code
    • Junie
      Junie
    • Replit
      Replit
    • Windsurf
      Windsurf
    • Cline
      Cline
    • Continue
      Continue
    • OpenCode
      OpenCode
    • OpenHands
      OpenHands
    • Roo Code
      Roo Code
    • Augment
      Augment
    • Goose
      Goose
    • Trae
      Trae
    • Zencoder
      Zencoder
    • Antigravity
      Antigravity
    ├─
    ├─
    └─

    About

    Master Entity Framework Core migrations with code-first approach, migration strategies, data seeding, rollback procedures, and production deployment patterns.

    SKILL.md

    .NET Entity Framework Core Migrations

    Master EF Core migrations for .NET 8+ with code-first database management.

    Setup

    # Install EF Core tools
    dotnet tool install --global dotnet-ef
    dotnet tool update --global dotnet-ef
    
    # Add EF Core packages
    dotnet add package Microsoft.EntityFrameworkCore.Design
    dotnet add package Microsoft.EntityFrameworkCore.SqlServer
    # Or PostgreSQL
    dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL
    

    DbContext Configuration

    public class AppDbContext : DbContext
    {
        public AppDbContext(DbContextOptions<AppDbContext> options)
            : base(options)
        {
        }
    
        public DbSet<Order> Orders { get; set; }
        public DbSet<Customer> Customers { get; set; }
    
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.ApplyConfigurationsFromAssembly(typeof(AppDbContext).Assembly);
    
            // Global query filters
            modelBuilder.Entity<Order>().HasQueryFilter(o => !o.IsDeleted);
    
            base.OnModelCreating(modelBuilder);
        }
    }
    
    // Entity Configuration
    public class OrderConfiguration : IEntityTypeConfiguration<Order>
    {
        public void Configure(EntityTypeBuilder<Order> builder)
        {
            builder.ToTable("Orders");
    
            builder.HasKey(o => o.Id);
    
            builder.Property(o => o.OrderNumber)
                .IsRequired()
                .HasMaxLength(20);
    
            builder.Property(o => o.TotalAmount)
                .HasColumnType("decimal(18,2)");
    
            builder.HasIndex(o => o.OrderNumber)
                .IsUnique();
    
            builder.HasOne(o => o.Customer)
                .WithMany(c => c.Orders)
                .HasForeignKey(o => o.CustomerId)
                .OnDelete(DeleteBehavior.Restrict);
    
            builder.HasMany(o => o.Items)
                .WithOne(i => i.Order)
                .HasForeignKey(i => i.OrderId)
                .OnDelete(DeleteBehavior.Cascade);
        }
    }
    

    Migration Commands

    # Add migration
    dotnet ef migrations add InitialCreate
    dotnet ef migrations add AddOrderStatus
    dotnet ef migrations add UpdateCustomerEmail
    
    # Update database
    dotnet ef database update
    
    # Update to specific migration
    dotnet ef database update AddOrderStatus
    
    # Rollback migration
    dotnet ef database update PreviousMigration
    
    # Remove last migration (if not applied)
    dotnet ef migrations remove
    
    # Generate SQL script
    dotnet ef migrations script
    dotnet ef migrations script InitialCreate AddOrderStatus
    
    # Generate idempotent script
    dotnet ef migrations script --idempotent
    
    # List migrations
    dotnet ef migrations list
    
    # Drop database
    dotnet ef database drop --force
    

    Migration File Structure

    public partial class AddOrderStatus : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.AddColumn<int>(
                name: "Status",
                table: "Orders",
                type: "int",
                nullable: false,
                defaultValue: 0);
    
            migrationBuilder.CreateIndex(
                name: "IX_Orders_Status",
                table: "Orders",
                column: "Status");
        }
    
        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DropIndex(
                name: "IX_Orders_Status",
                table: "Orders");
    
            migrationBuilder.DropColumn(
                name: "Status",
                table: "Orders");
        }
    }
    

    Data Seeding

    // In OnModelCreating
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<OrderStatus>().HasData(
            new OrderStatus { Id = 1, Name = "Pending" },
            new OrderStatus { Id = 2, Name = "Processing" },
            new OrderStatus { Id = 3, Name = "Shipped" },
            new OrderStatus { Id = 4, Name = "Delivered" }
        );
    }
    
    // Or in migration
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.InsertData(
            table: "OrderStatuses",
            columns: new[] { "Id", "Name" },
            values: new object[,]
            {
                { 1, "Pending" },
                { 2, "Processing" },
                { 3, "Shipped" },
                { 4, "Delivered" }
            });
    }
    

    Custom SQL in Migrations

    protected override void Up(MigrationBuilder migrationBuilder)
    {
        // Execute raw SQL
        migrationBuilder.Sql(@"
            CREATE INDEX IX_Orders_CreatedAt_Status
            ON Orders (CreatedAt, Status)
            WHERE IsDeleted = 0
        ");
    
        // Create stored procedure
        migrationBuilder.Sql(@"
            CREATE PROCEDURE GetOrdersByCustomer
                @CustomerId uniqueidentifier
            AS
            BEGIN
                SELECT * FROM Orders
                WHERE CustomerId = @CustomerId
                AND IsDeleted = 0
            END
        ");
    
        // Create view
        migrationBuilder.Sql(@"
            CREATE VIEW vw_ActiveOrders AS
            SELECT o.*, c.Name AS CustomerName
            FROM Orders o
            INNER JOIN Customers c ON o.CustomerId = c.Id
            WHERE o.IsDeleted = 0
        ");
    }
    
    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.Sql("DROP VIEW IF EXISTS vw_ActiveOrders");
        migrationBuilder.Sql("DROP PROCEDURE IF EXISTS GetOrdersByCustomer");
        migrationBuilder.Sql("DROP INDEX IF EXISTS IX_Orders_CreatedAt_Status ON Orders");
    }
    

    Production Deployment

    // Program.cs - Apply migrations on startup (development only)
    if (app.Environment.IsDevelopment())
    {
        using var scope = app.Services.CreateScope();
        var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
        await db.Database.MigrateAsync();
    }
    
    // Production - Generate SQL scripts
    // dotnet ef migrations script --idempotent --output migrations.sql
    // Review and apply scripts manually
    
    // Or use migration bundles (EF Core 6+)
    // dotnet ef migrations bundle --self-contained -r linux-x64
    // ./efbundle --connection "Server=..."
    

    Migration Strategies

    1. Script-Based (Recommended for Production)

    # Generate script
    dotnet ef migrations script --idempotent --output migration.sql
    
    # Review script
    # Apply via SQL tool or deployment pipeline
    

    2. Runtime Migration

    // Only in development/staging
    await dbContext.Database.MigrateAsync();
    

    3. Migration Bundles

    # Create bundle
    dotnet ef migrations bundle --self-contained -r linux-x64
    
    # Deploy and run
    ./efbundle --connection "Server=prod;Database=MyDb;..."
    

    Handling Migration Conflicts

    // Multiple developers scenario:
    // 1. Pull latest code
    git pull origin main
    
    // 2. If migration conflicts, remove your migration
    dotnet ef migrations remove
    
    // 3. Create new migration
    dotnet ef migrations add YourFeature
    
    // 4. Test migration
    dotnet ef database update
    

    Rolling Back Migrations

    # Rollback to specific migration
    dotnet ef database update PreviousMigration
    
    # Rollback all
    dotnet ef database update 0
    
    # Generate rollback script
    dotnet ef migrations script CurrentMigration PreviousMigration --output rollback.sql
    

    Best Practices

    1. Never Modify Applied Migrations - Create new migration instead
    2. Review Generated Migrations - Check SQL before applying
    3. Test Migrations - Test on copy of production data
    4. Use Transactions - Migrations run in transactions by default
    5. Backup Before Migration - Always backup production database
    6. Idempotent Scripts - Use --idempotent flag for production
    7. Version Control - Commit migrations with code changes
    8. Data Migration - Separate data migrations from schema migrations

    Common Patterns

    // Adding nullable column then making it required
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        // Step 1: Add nullable column
        migrationBuilder.AddColumn<string>(
            name: "Email",
            table: "Customers",
            nullable: true);
    
        // Step 2: Update existing rows
        migrationBuilder.Sql("UPDATE Customers SET Email = 'unknown@example.com' WHERE Email IS NULL");
    
        // Step 3: Make column required
        migrationBuilder.AlterColumn<string>(
            name: "Email",
            table: "Customers",
            nullable: false);
    }
    
    // Renaming column
    migrationBuilder.RenameColumn(
        name: "OldName",
        table: "TableName",
        newName: "NewName");
    
    // Changing column type
    migrationBuilder.AlterColumn<decimal>(
        name: "Price",
        table: "Products",
        type: "decimal(18,2)",
        nullable: false,
        oldClrType: typeof(float));
    
    Recommended Servers
    Supabase
    Supabase
    Repository
    onesmartguy/next-level-real-estate
    Files