[{"data":1,"prerenderedAt":110},["ShallowReactive",2],{"qa-\u002Fdotnet\u002Fentity-framework\u002Fmigrations":3},{"page":4,"siblings":93,"blog":107},{"id":5,"title":6,"body":7,"description":11,"difficulty":14,"extension":15,"framework":16,"frameworkSlug":17,"meta":18,"navigation":19,"order":12,"path":20,"questions":21,"questionsCount":84,"related":85,"seo":86,"seoDescription":87,"stem":88,"subtopic":6,"topic":89,"topicSlug":90,"updated":91,"__hash__":92},"qa\u002Fdotnet\u002Fentity-framework\u002Fmigrations.md","Migrations",{"type":8,"value":9,"toc":10},"minimark",[],{"title":11,"searchDepth":12,"depth":12,"links":13},"",2,[],"medium","md",".NET Core","dotnet",{},true,"\u002Fdotnet\u002Fentity-framework\u002Fmigrations",[22,27,31,35,39,43,47,51,55,59,63,67,72,76,80],{"id":23,"difficulty":24,"q":25,"a":26},"ef-migrations-what","easy","What are EF Core migrations and why do you use them instead of manual schema scripts?","**EF Core migrations** are versioned C# classes that translate model changes into\ndatabase schema operations. Each migration has an `Up` (apply) and a `Down` (revert)\nmethod, making schema evolution repeatable and reversible.\n\n```csharp\n\u002F\u002F 1. Add a migration after changing the model:\n\u002F\u002F dotnet ef migrations add AddOrderStatusColumn\n\n\u002F\u002F Generated migration file:\npublic partial class AddOrderStatusColumn : Migration\n{\n    protected override void Up(MigrationBuilder migrationBuilder)\n    {\n        migrationBuilder.AddColumn\u003Cstring>(\n            name: \"Status\",\n            table: \"Orders\",\n            type: \"nvarchar(50)\",\n            nullable: false,\n            defaultValue: \"Pending\");\n\n        migrationBuilder.CreateIndex(\n            name: \"IX_Orders_Status\",\n            table: \"Orders\",\n            column: \"Status\");\n    }\n\n    protected override void Down(MigrationBuilder migrationBuilder)\n    {\n        migrationBuilder.DropIndex(\"IX_Orders_Status\", \"Orders\");\n        migrationBuilder.DropColumn(\"Status\", \"Orders\");\n    }\n}\n\n\u002F\u002F 2. Apply to the database:\n\u002F\u002F dotnet ef database update\n\u002F\u002F Or programmatically at startup:\nawait db.Database.MigrateAsync(); \u002F\u002F applies all pending migrations\n```\n\nBenefits over manual scripts: migrations are source-controlled, tied to the model,\nreversible with `Down`, and apply in order via the `__EFMigrationsHistory` table.\n\n**Rule of thumb:** One migration per logical schema change. Never edit a migration\nonce it's been applied to any shared environment — add a new migration instead.\n",{"id":28,"difficulty":24,"q":29,"a":30},"ef-migrations-workflow","What is the standard EF Core migration workflow from model change to production?","The migration workflow moves schema changes through dev → CI → staging → prod in\na controlled, repeatable way.\n\n```bash\n# 1. Change the model (add property, new entity, new relationship)\n\n# 2. Generate the migration:\ndotnet ef migrations add \u003CMigrationName> --project MyApp.Data --startup-project MyApp.Api\n\n# 3. Review the generated migration file — always inspect Up\u002FDown before committing:\n#    migrations\u002F\u003Ctimestamp>_\u003CMigrationName>.cs\n\n# 4. Apply to local dev DB:\ndotnet ef database update\n\n# 5. Commit migration files alongside the model change — one PR, both together.\n\n# 6. Apply in CI (integration tests run against a real migrated DB):\n#    services.AddDbContext\u003CAppDbContext>(...);\n#    db.Database.Migrate(); \u002F\u002F in test fixture setup\n\n# 7. Apply to staging and production — never dotnet ef in prod:\n#    Option A: db.Database.MigrateAsync() in app startup (simple, single-server)\n#    Option B: migration bundle (preferred for containerised deployments):\ndotnet ef migrations bundle --self-contained -o migrate\n# Then run: .\u002Fmigrate --connection \"...\"\n```\n\n```csharp\n\u002F\u002F Programmatic startup migration (option A):\nvar app = builder.Build();\n\nusing (var scope = app.Services.CreateScope())\n{\n    var db = scope.ServiceProvider.GetRequiredService\u003CAppDbContext>();\n    await db.Database.MigrateAsync(); \u002F\u002F idempotent — skips applied migrations\n}\n\nawait app.RunAsync();\n```\n\n**Rule of thumb:** Always commit migration files with the model change. Never apply\n`dotnet ef database update` directly to production — use `MigrateAsync` at startup\nor a migration bundle in a deploy step.\n",{"id":32,"difficulty":24,"q":33,"a":34},"ef-migrations-history","What is the __EFMigrationsHistory table and how does EF Core use it?","**`__EFMigrationsHistory`** is a bookkeeping table EF Core creates and maintains.\nIt records every applied migration by name and the EF Core product version, giving\n`MigrateAsync` its idempotency.\n\n```sql\n-- Created automatically by EF Core; looks like:\nCREATE TABLE __EFMigrationsHistory (\n    MigrationId     nvarchar(150) NOT NULL,\n    ProductVersion  nvarchar(32)  NOT NULL,\n    CONSTRAINT PK___EFMigrationsHistory PRIMARY KEY (MigrationId)\n);\n\n-- After applying two migrations, the table contains:\n-- | MigrationId                            | ProductVersion |\n-- | 20240101000000_InitialCreate            | 8.0.0          |\n-- | 20240615120000_AddOrderStatusColumn     | 8.0.0          |\n```\n\n```csharp\n\u002F\u002F Check pending migrations programmatically:\nvar pending = await db.Database.GetPendingMigrationsAsync();\nConsole.WriteLine($\"{pending.Count()} migration(s) pending\");\n\n\u002F\u002F List applied migrations:\nvar applied = await db.Database.GetAppliedMigrationsAsync();\n\n\u002F\u002F Remove a migration that hasn't been applied yet (resets the snapshot):\n\u002F\u002F dotnet ef migrations remove\n\n\u002F\u002F \"Fake\" applying a migration (schema already exists but EF doesn't know):\n\u002F\u002F dotnet ef database update --target MigrationName\n\u002F\u002F Then manually insert a row into __EFMigrationsHistory.\n```\n\n**Rule of thumb:** Never edit `__EFMigrationsHistory` manually in production unless\nyou are recovering from a partial failed migration. If a migration fails mid-run, fix\nthe migration and rerun — don't delete the history row.\n",{"id":36,"difficulty":24,"q":37,"a":38},"ef-data-seeding","How do you seed data with EF Core migrations?","EF Core provides **model-based seeding** via `HasData` in `OnModelCreating` for\nstatic reference data, and **custom seeding** code for dynamic or environment-specific\ndata.\n\n```csharp\n\u002F\u002F Model-based seeding — becomes part of the migration:\nprotected override void OnModelCreating(ModelBuilder mb)\n{\n    mb.Entity\u003CCategory>().HasData(\n        new Category { Id = 1, Name = \"Electronics\", Slug = \"electronics\" },\n        new Category { Id = 2, Name = \"Clothing\",    Slug = \"clothing\"    },\n        new Category { Id = 3, Name = \"Books\",       Slug = \"books\"       }\n    );\n}\n\u002F\u002F dotnet ef migrations add SeedCategories generates an InsertData migration.\n\u002F\u002F EF Core tracks these rows — updating HasData generates an UpdateData migration.\n\u002F\u002F Primary keys must be set explicitly (no DB-generated keys for seed data).\n\n\u002F\u002F Custom startup seeding — for dynamic data not tracked by migrations:\npublic static class DatabaseSeeder\n{\n    public static async Task SeedAsync(AppDbContext db)\n    {\n        if (await db.Users.AnyAsync(u => u.Email == \"admin@example.com\"))\n            return; \u002F\u002F idempotent — skip if already seeded\n\n        db.Users.Add(new User\n        {\n            Email    = \"admin@example.com\",\n            Role     = \"Admin\",\n            Password = PasswordHasher.Hash(\"change-me-on-first-login\")\n        });\n\n        await db.SaveChangesAsync();\n    }\n}\n\n\u002F\u002F Call after MigrateAsync at startup:\nawait db.Database.MigrateAsync();\nawait DatabaseSeeder.SeedAsync(db);\n```\n\n**Rule of thumb:** Use `HasData` only for static reference data with stable IDs\n(lookup tables, role definitions). Use custom seeder code for admin users, test data,\nor anything that varies by environment.\n",{"id":40,"difficulty":14,"q":41,"a":42},"ef-design-time-factory","What is a design-time DbContext factory and when do you need one?","A **design-time factory** (`IDesignTimeDbContextFactory\u003CT>`) tells EF migration\ntooling how to construct the `DbContext` when the startup project can't be used\nas-is — for example when the context is in a separate class library.\n\n```csharp\n\u002F\u002F Required when:\n\u002F\u002F - AppDbContext lives in a class library (no Program.cs to discover)\n\u002F\u002F - Context constructor needs non-DI arguments at design time\n\u002F\u002F - Connection string differs between design time and runtime\n\npublic class AppDbContextFactory : IDesignTimeDbContextFactory\u003CAppDbContext>\n{\n    public AppDbContext CreateDbContext(string[] args)\n    {\n        \u002F\u002F Read config from appsettings.json at design time:\n        var config = new ConfigurationBuilder()\n            .SetBasePath(Directory.GetCurrentDirectory())\n            .AddJsonFile(\"appsettings.json\")\n            .AddEnvironmentVariables()\n            .Build();\n\n        var options = new DbContextOptionsBuilder\u003CAppDbContext>()\n            .UseSqlServer(config.GetConnectionString(\"Default\"))\n            .Options;\n\n        return new AppDbContext(options);\n    }\n}\n```\n\nEF tooling (`dotnet ef migrations add`, `dotnet ef database update`) automatically\ndiscovers `IDesignTimeDbContextFactory\u003CT>` implementations at design time.\n\n```bash\n# Specify both projects when context is in a library:\ndotnet ef migrations add InitialCreate \\\n    --project MyApp.Data \\          # where DbContext lives\n    --startup-project MyApp.Api      # where appsettings.json lives\n```\n\n**Rule of thumb:** Always create a design-time factory when `AppDbContext` is in a\nclass library. Without it, `dotnet ef` either fails or picks the wrong connection string.\n",{"id":44,"difficulty":14,"q":45,"a":46},"ef-migration-bundles","What are EF Core migration bundles and why are they preferred for CI\u002FCD?","**Migration bundles** are standalone executables that apply pending migrations — no\n.NET SDK or EF CLI required at deploy time. They are the production-safe alternative\nto running `dotnet ef database update` in a pipeline.\n\n```bash\n# Build a self-contained migration bundle:\ndotnet ef migrations bundle \\\n    --self-contained \\\n    --runtime linux-x64 \\\n    -o .\u002Fmigrate \\\n    --project MyApp.Data \\\n    --startup-project MyApp.Api\n\n# This produces a single binary: .\u002Fmigrate\n\n# Run in CI\u002FCD or Kubernetes init container:\n.\u002Fmigrate --connection \"Server=prod;Database=App;User=sa;Password=...\"\n\n# Flags:\n# --target \u003CMigrationName>   — migrate to a specific version (rollback)\n# --no-transactions          — disable wrapping each migration in a transaction\n# --verbose                  — show individual SQL statements\n```\n\n```yaml\n# Kubernetes — init container applies migrations before the app starts:\ninitContainers:\n  - name: db-migrate\n    image: myapp-migrate:latest  # contains the bundle\n    command: [\".\u002Fmigrate\"]\n    env:\n      - name: ConnectionStrings__Default\n        valueFrom:\n          secretKeyRef:\n            name: db-secret\n            key: connection-string\n```\n\n**Rule of thumb:** Build a migration bundle as part of CI and run it in an init\ncontainer or deploy step — never auto-migrate inside the application process\nin a multi-replica deployment (races between replicas).\n",{"id":48,"difficulty":14,"q":49,"a":50},"ef-rollback","How do you roll back a migration in EF Core?","EF Core supports targeted rollback via `dotnet ef database update \u003Ctarget>`, which\ncalls each migration's `Down` method in reverse order.\n\n```bash\n# List all migrations (applied and pending):\ndotnet ef migrations list\n\n# Roll back to a specific migration (exclusive — that migration stays applied):\ndotnet ef database update AddOrderStatusColumn\n\n# Roll back ALL migrations (empty database — __EFMigrationsHistory stays):\ndotnet ef database update 0\n\n# Remove the last migration that hasn't been applied to any shared DB:\ndotnet ef migrations remove\n# Rewrites the model snapshot — only safe if the migration hasn't been shared.\n```\n\n```csharp\n\u002F\u002F Programmatic rollback (useful in integration tests):\nawait db.Database.MigrateAsync();  \u002F\u002F apply up to latest\n\n\u002F\u002F Or target a specific migration in a test fixture:\nawait db.GetService\u003CIMigrator>()\n        .MigrateAsync(\"20240101000000_InitialCreate\"); \u002F\u002F migrate to this point\n```\n\nProduction rollback considerations:\n- `Down` methods must be written carefully — data loss is possible (e.g., `DropColumn`).\n- For zero-downtime deploys, prefer **forward-only** migrations (never auto-populate `Down`).\n- Always back up the database before rolling back in production.\n\n**Rule of thumb:** Write `Down` methods when the migration is purely structural (indexes,\ncolumn renames). For migrations that delete columns or tables, leave `Down` empty and add\na forward migration to recover — never roll back data loss in production.\n",{"id":52,"difficulty":14,"q":53,"a":54},"ef-migration-squashing","How do you squash or consolidate many EF Core migrations?","As migrations accumulate, startup time and migration history grow. **Squashing**\nreplaces many small migrations with a single baseline migration.\n\n```bash\n# 1. Ensure all team environments are up to date with latest migration.\n\n# 2. Delete all existing migration files:\nrm Migrations\u002F*.cs   # keep only the Designer snapshot\n\n# 3. Create a new baseline migration from the current model snapshot:\ndotnet ef migrations add Baseline --ignore-changes\n# --ignore-changes: generates a migration without diffing (uses the current model)\n\n# 4. Mark the new migration as already applied on existing databases:\nINSERT INTO __EFMigrationsHistory (MigrationId, ProductVersion)\nVALUES ('20260101000000_Baseline', '8.0.0');\n# Then delete all previous rows from the table.\n\n# 5. Fresh databases get the Baseline migration applied normally.\n```\n\n```csharp\n\u002F\u002F Alternative: EnsureCreated for dev\u002Ftest (no migrations at all):\nawait db.Database.EnsureCreatedAsync();\n\u002F\u002F Creates schema from the current model snapshot — no migration history.\n\u002F\u002F Useful in tests; NOT a replacement for migrations in production.\n```\n\n**Rule of thumb:** Squash migrations when the history is unwieldy (50+ migrations)\nOR when you want a clean baseline after a major refactor. Coordinate with all\nenvironments before squashing — every DB must be at the latest migration first.\n",{"id":56,"difficulty":14,"q":57,"a":58},"ef-generated-sql","How do you inspect the SQL that EF Core migration commands generate?","EF Core provides several ways to preview SQL before applying it — critical for\ncatching unexpected schema changes in production.\n\n```bash\n# Script the migration instead of applying it:\ndotnet ef migrations script                    # all migrations → SQL file\ndotnet ef migrations script FromMigration ToMigration  # range\n\n# Idempotent script (safe to run multiple times):\ndotnet ef migrations script --idempotent\n# Wraps each migration in IF NOT EXISTS checks against __EFMigrationsHistory\n\n# Preview what update would do (no DB changes):\ndotnet ef database update --dry-run           # prints SQL, doesn't execute\n```\n\n```csharp\n\u002F\u002F Log all generated SQL at runtime via EF Core logging:\nbuilder.Services.AddDbContext\u003CAppDbContext>(options =>\n    options\n        .UseSqlServer(connectionString)\n        .LogTo(Console.WriteLine, LogLevel.Information)    \u002F\u002F all EF logs\n        .EnableSensitiveDataLogging());                    \u002F\u002F include param values\n\n\u002F\u002F Or capture in a StringBuilder for tests:\nvar log = new StringBuilder();\noptions.LogTo(msg => log.AppendLine(msg), LogLevel.Information);\n```\n\n**Rule of thumb:** Always run `dotnet ef migrations script --idempotent` in CI\nand review the output before applying to staging or production. Never apply a\nmigration you haven't read.\n",{"id":60,"difficulty":14,"q":61,"a":62},"ef-multiple-dbcontexts","How do you manage multiple DbContexts in one application?","Some applications split concerns across multiple `DbContext` types — for example,\nseparate contexts for the main domain and for identity management. Each needs its\nown migration history table.\n\n```csharp\n\u002F\u002F Two separate contexts — each with its own schema area:\npublic class AppDbContext : DbContext\n{\n    public DbSet\u003COrder> Orders { get; set; }\n    public DbSet\u003CProduct> Products { get; set; }\n}\n\npublic class IdentityDbContext : IdentityDbContext\u003CApplicationUser>\n{\n    \u002F\u002F ASP.NET Core Identity tables (AspNetUsers, AspNetRoles, etc.)\n}\n\n\u002F\u002F Register both:\nbuilder.Services.AddDbContext\u003CAppDbContext>(o =>\n    o.UseSqlServer(connectionString));\n\nbuilder.Services.AddDbContext\u003CIdentityDbContext>(o =>\n    o.UseSqlServer(connectionString));\n\n\u002F\u002F Separate migration history tables to avoid conflicts:\nprotected override void OnModelCreating(ModelBuilder mb)\n{\n    mb.HasDefaultSchema(\"identity\"); \u002F\u002F or use MigrationsHistoryTable\n}\n\n\u002F\u002F Or configure explicitly:\noptions.UseSqlServer(conn, sql =>\n    sql.MigrationsHistoryTable(\"__IdentityMigrationsHistory\", \"identity\"));\n```\n\n```bash\n# Run migrations per context:\ndotnet ef migrations add InitialCreate --context AppDbContext\ndotnet ef migrations add IdentityInit   --context IdentityDbContext\n\ndotnet ef database update --context AppDbContext\ndotnet ef database update --context IdentityDbContext\n```\n\n**Rule of thumb:** Use separate `DbContext` types for bounded contexts or separate\ninfrastructure concerns (identity, tenancy, auditing). Always configure distinct\n`MigrationsHistoryTable` names to prevent migration conflicts.\n",{"id":64,"difficulty":24,"q":65,"a":66},"ef-ensure-created-vs-migrate","What is the difference between EnsureCreated and MigrateAsync?","**`EnsureCreated`** creates the database schema from the current EF model snapshot in\none step — no migration files involved. **`MigrateAsync`** applies versioned migration\nfiles in order and records them in `__EFMigrationsHistory`.\n\n```csharp\n\u002F\u002F EnsureCreated — creates schema if the DB doesn't exist; no-op if it does:\nawait db.Database.EnsureCreatedAsync();\n\u002F\u002F Good for: unit\u002Fintegration tests, quick prototyping, in-memory database\n\u002F\u002F Bad for: production — bypasses migrations; EF can't diff or evolve the schema later\n\n\u002F\u002F MigrateAsync — applies all pending migrations in order; idempotent:\nawait db.Database.MigrateAsync();\n\u002F\u002F Good for: production, staging, CI — schema is versioned and repeatable\n\u002F\u002F Requires migration files to exist first (dotnet ef migrations add)\n\n\u002F\u002F Critical incompatibility:\n\u002F\u002F If you call EnsureCreated on a database, then later switch to migrations,\n\u002F\u002F MigrateAsync fails — the schema exists but __EFMigrationsHistory is empty.\n\u002F\u002F EF thinks migrations haven't been applied and tries to re-create tables → error.\n\n\u002F\u002F Test setup pattern — EnsureCreated is fine because tests always start fresh:\npublic class TestFixture : IAsyncLifetime\n{\n    private readonly AppDbContext _db;\n\n    public async Task InitializeAsync()\n    {\n        await _db.Database.EnsureDeletedAsync(); \u002F\u002F clean slate\n        await _db.Database.EnsureCreatedAsync(); \u002F\u002F schema from model snapshot\n    }\n\n    public async Task DisposeAsync()\n        => await _db.Database.EnsureDeletedAsync();\n}\n```\n\n**Rule of thumb:** Use `EnsureCreated` only in tests or demos with an in-memory or\nSQLite database. Use `MigrateAsync` everywhere else — it's the only approach that\nsupports schema evolution without data loss.\n",{"id":68,"difficulty":69,"q":70,"a":71},"ef-pending-model-changes","hard","How do you detect and prevent model\u002Fmigration drift in CI?","**Model\u002Fmigration drift** occurs when the model changes but no migration is added,\nmeaning the deployed schema won't match the running code. Detecting this in CI\nprevents production failures.\n\n```bash\n# EF Core 8+ — dotnet ef migrations has-pending-model-changes exits non-zero\n# if the model snapshot differs from the current model (no migration was generated):\ndotnet ef migrations has-pending-model-changes \\\n    --project MyApp.Data \\\n    --startup-project MyApp.Api\n\n# CI step (GitHub Actions \u002F bash):\nif ! dotnet ef migrations has-pending-model-changes ...; then\n    echo \"ERROR: Model changed without a migration. Run 'dotnet ef migrations add'.\"\n    exit 1\nfi\n```\n\n```csharp\n\u002F\u002F At startup — warn if any migration is pending (alternative CI check):\nvar pending = await db.Database.GetPendingMigrationsAsync();\nif (pending.Any())\n    throw new InvalidOperationException(\n        $\"Database has {pending.Count()} pending migration(s). Run MigrateAsync or apply the bundle.\");\n\n\u002F\u002F Integration test guard:\n[Fact]\npublic void NoUnappliedMigrations()\n{\n    using var db = CreateTestContext();\n    db.Database.Migrate();\n    var pending = db.Database.GetPendingMigrations();\n    Assert.Empty(pending);\n}\n```\n\n**Rule of thumb:** Add `dotnet ef migrations has-pending-model-changes` as a CI step.\nGate merges on a clean result — a model change without a migration is a production outage\nwaiting to happen.\n",{"id":73,"difficulty":14,"q":74,"a":75},"ef-migrations-transactions","Are EF Core migrations applied inside a database transaction?","By default, each migration's `Up` method runs inside its own **database transaction**,\nso a failing migration is rolled back cleanly. However, some DDL statements are\nnon-transactional on certain databases (SQL Server: `CREATE DATABASE`, `ALTER DATABASE`;\nPostgreSQL: certain index operations).\n\n```csharp\n\u002F\u002F Default behaviour — each migration is wrapped automatically:\npublic partial class AddOrderStatusColumn : Migration\n{\n    \u002F\u002F EF Core wraps this Up() in a transaction unless you suppress it:\n    protected override void Up(MigrationBuilder migrationBuilder)\n    {\n        migrationBuilder.AddColumn\u003Cstring>(\n            name: \"Status\",\n            table: \"Orders\",\n            type: \"nvarchar(50)\",\n            nullable: false,\n            defaultValue: \"Pending\");\n    }\n\n    \u002F\u002F Opt out of the transaction for this migration (e.g., CREATE INDEX CONCURRENTLY on Postgres):\n    protected override void Up(MigrationBuilder migrationBuilder)\n    {\n        migrationBuilder.Sql(\n            \"CREATE INDEX CONCURRENTLY IX_Orders_Status ON Orders(Status);\",\n            suppressTransaction: true); \u002F\u002F run outside a transaction\n    }\n}\n\n\u002F\u002F Apply without wrapping migrations in transactions (bundle flag):\n\u002F\u002F .\u002Fmigrate --no-transactions\n\n\u002F\u002F Manual transaction via MigrationBuilder.BeginTransaction is not available —\n\u002F\u002F the framework controls the transaction boundary. Use suppressTransaction: true\n\u002F\u002F only for statements that cannot run inside a transaction.\n```\n\nPartial migration failure in production:\n- If the migration throws after some statements but inside the EF transaction, the DB is rolled back.\n- If `suppressTransaction: true` statements fail, the DB is left in a partial state — you must fix\n  and rerun manually. Always script `--idempotent` SQL before running these.\n\n**Rule of thumb:** Rely on EF's default transaction wrapping. Use `suppressTransaction: true`\nonly for database-specific statements that explicitly forbid transactions. Test those migrations\non a staging clone before production.\n",{"id":77,"difficulty":14,"q":78,"a":79},"ef-migration-columns-rename","How do you rename a column in an EF Core migration without losing data?","EF Core's `RenameColumn` migrates column names without dropping and recreating them,\npreserving existing data. Without it, EF would generate a `DropColumn` + `AddColumn`\npair, which deletes the data in that column.\n\n```csharp\n\u002F\u002F Step 1 — rename the property in the entity class:\npublic class Customer\n{\n    public int Id { get; set; }\n    \u002F\u002F Before: public string FullName { get; set; } = \"\";\n    public string DisplayName { get; set; } = \"\";  \u002F\u002F renamed property\n}\n\n\u002F\u002F Step 2 — generate the migration:\n\u002F\u002F dotnet ef migrations add RenameCustomerDisplayName\n\n\u002F\u002F The auto-generated migration MAY produce DropColumn + AddColumn (data loss!):\n\u002F\u002F Fix it manually to use RenameColumn instead:\npublic partial class RenameCustomerDisplayName : Migration\n{\n    protected override void Up(MigrationBuilder migrationBuilder)\n    {\n        \u002F\u002F Safe — preserves column data:\n        migrationBuilder.RenameColumn(\n            name: \"FullName\",\n            table: \"Customers\",\n            newName: \"DisplayName\");\n    }\n\n    protected override void Down(MigrationBuilder migrationBuilder)\n    {\n        migrationBuilder.RenameColumn(\n            name: \"DisplayName\",\n            table: \"Customers\",\n            newName: \"FullName\");\n    }\n}\n\n\u002F\u002F Step 3 — map the new column name to the property if needed:\nmodelBuilder.Entity\u003CCustomer>()\n    .Property(c => c.DisplayName)\n    .HasColumnName(\"DisplayName\"); \u002F\u002F explicit; EF derives it from property name by default\n```\n\n**Rule of thumb:** Always inspect auto-generated migrations before applying them.\nWhen renaming a column, replace any `DropColumn`\u002F`AddColumn` pair with a single\n`RenameColumn` call to avoid silent data loss.\n",{"id":81,"difficulty":69,"q":82,"a":83},"ef-migration-separate-assembly","How do you put EF Core migrations in a separate assembly from the DbContext?","Placing migrations in a dedicated assembly (e.g., `MyApp.Migrations`) keeps the\ndata layer clean and allows independent versioning. It requires configuring both\nthe `MigrationsAssembly` option and a design-time factory.\n\n```csharp\n\u002F\u002F Project layout:\n\u002F\u002F MyApp.Data        — contains AppDbContext, entity configs\n\u002F\u002F MyApp.Migrations  — contains only migration files\n\u002F\u002F MyApp.Api         — startup project\n\n\u002F\u002F In MyApp.Api Program.cs — tell EF where migrations live:\nbuilder.Services.AddDbContext\u003CAppDbContext>(options =>\n    options.UseSqlServer(\n        connectionString,\n        sql => sql.MigrationsAssembly(\"MyApp.Migrations\"))); \u002F\u002F assembly name\n\n\u002F\u002F In MyApp.Migrations — design-time factory so dotnet ef can build the context:\npublic class AppDbContextFactory : IDesignTimeDbContextFactory\u003CAppDbContext>\n{\n    public AppDbContext CreateDbContext(string[] args)\n    {\n        var config = new ConfigurationBuilder()\n            .SetBasePath(Directory.GetCurrentDirectory())\n            .AddJsonFile(\"appsettings.json\", optional: true)\n            .AddEnvironmentVariables()\n            .Build();\n\n        var opts = new DbContextOptionsBuilder\u003CAppDbContext>()\n            .UseSqlServer(\n                config.GetConnectionString(\"Default\"),\n                sql => sql.MigrationsAssembly(\"MyApp.Migrations\"))\n            .Options;\n\n        return new AppDbContext(opts);\n    }\n}\n```\n\n```bash\n# Generate a migration — target MyApp.Migrations, startup project MyApp.Api:\ndotnet ef migrations add InitialCreate \\\n    --project MyApp.Migrations \\\n    --startup-project MyApp.Api \\\n    --context AppDbContext\n\n# Apply:\ndotnet ef database update \\\n    --project MyApp.Migrations \\\n    --startup-project MyApp.Api\n```\n\n**Rule of thumb:** Move migrations to a separate assembly for large solutions where\nthe data layer is shared across multiple apps (e.g., web API + background worker).\nAlways keep `MigrationsAssembly` in sync between runtime registration and the\ndesign-time factory.\n",15,null,{"description":11},"EF Core migrations interview questions — Add-Migration, Up\u002FDown methods, MigrateAsync, migration bundles, seeding, and rollback strategies.","dotnet\u002Fentity-framework\u002Fmigrations","Entity Framework Core","entity-framework","2026-06-23","oMk5ZPvNRmGINCgzvsO_Xl5h7BqSVTuHIEWmeHTbRYg",[94,98,99,103],{"subtopic":95,"path":96,"order":97},"DbContext & DbSet","\u002Fdotnet\u002Fentity-framework\u002Fdbcontext-dbset",1,{"subtopic":6,"path":20,"order":12},{"subtopic":100,"path":101,"order":102},"Querying","\u002Fdotnet\u002Fentity-framework\u002Fquerying",3,{"subtopic":104,"path":105,"order":106},"Relationships","\u002Fdotnet\u002Fentity-framework\u002Frelationships",4,{"path":108,"title":109},"\u002Fblog\u002Fdotnet-ef-migrations","Working with EF Core Migrations",1782244118604]