Post

Fighting the EF Core Migration Monster (Again)

A developer's tale of frustration and survival while navigating EF Core migrations, foreign key chaos, and the power of starting from scratch.

Fighting the EF Core Migration Monster (Again)

If there’s one thing that can turn a calm day of coding into a descent into madness, it’s wrestling with Entity Framework Core migrations. And lately, I’ve been in the ring more times than I care to count.

I’m currently working on my Subspace API—think of it as a Star Trek episode database wrapped in an ASP.NET Core MVC API. Everything was humming along nicely until I made the innocent mistake of expanding my database schema. That’s when EF Core decided to throw a tantrum.

Foreign Keys: The Pettiest of Gatekeepers

I get that EF Core is trying to be helpful—”don’t let invalid data in”, and all that. But wow, is it picky about foreign keys. If you even think about altering a table that’s referenced by another, EF will flip the table (pun intended). Want to add a new relationship? You’d better pray that your navigation properties are correctly set, your cascade delete is explicitly defined, and that you haven’t left behind any phantom constraints from previous attempts. One misstep and you’re met with errors that sound like they were spat out by a deeply offended SQL Server.

My Default Fix: The Nuclear Option

Now, I know there are “proper” ways to fix migration problems. You can hand-edit migration files, roll back selectively, and try to coax EF into doing the right thing. And sometimes I do try. But more often than not, I just reach for the nuclear option: delete the migrations folder and start again from scratch.

Sure, it’s not elegant. But after staring down yet another The ALTER TABLE statement conflicted with the FOREIGN KEY constraint message, you stop caring about elegance. Sometimes you’ve just got to blow it up and rebuild. Thankfully, EF makes this fairly painless if your model is in sync and your seed data behaves. (Big ifs.)

Subspace API: The Migration Maze

With the Subspace API, I found myself in a particularly frustrating loop. The project has several entities—Series, Episodes, Characters, etc.—and naturally, they’re all interrelated. I ran into issues where EF Core wouldn’t run the migration steps in an order that SQL Server was happy with. It tried to add foreign keys before the dependent tables existed. Lovely.

After several failed attempts, I ended up breaking the migration down into multiple migrations, manually tweaking the model bit by bit, adding just enough structure to not trigger another cascade of errors. First, create the basic tables. Then, another migration to add relationships. Then another to seed the data. It worked… eventually. But it felt like trying to build a starship in a wind tunnel.

So, if you’re reading this while stuck in a migration spiral: you’re not alone. EF Core is powerful, yes, but it has all the grace of a clingy ex when it comes to database changes. My advice? Keep backups. Embrace the delete key. And if all else fails, remember—sometimes it’s faster to start again than to fix what’s broken.

Tips Learned the Hard Way

If you’re navigating EF Core migrations and want to preserve your sanity, here are some hard-earned lessons from the trenches:

  1. Delete Your Migrations Folder Without Shame If you’re still in early development and the database isn’t in production, don’t be afraid to nuke it all and start again. dotnet ef migrations add InitialCreate is your old friend. Trust it. Use it. Abuse it.

  2. Break Complex Schema Changes Into Smaller Migrations Trying to do everything in one go is a recipe for foreign key meltdowns. Add the tables first, then add the relationships. If you can, build your schema in steps and migrate as you go.

  3. EF Core Is Not Psychic
    If EF isn’t picking up your relationships, it’s probably because you forgot to set one of the following:

    1
    2
    
     public int ForeignKeyId { get; set; }
     public EntityType NavigationProperty { get; set; }
    

    You need both. Not one. Not the other. Both.

  4. Use HasData() Carefully with Relationships Seeding data that relies on foreign keys can be painful. EF Core doesn’t always guarantee insert order. Make sure your seed data IDs align perfectly, or you’ll end up wondering why your data vanishes silently (or worse, fails loudly).

  5. Don’t Trust EF to Order Table Creation Logically EF doesn’t always generate migrations in the correct dependency order—especially when circular references or deep nesting are involved. If you’re getting constraint errors, check your migration file. You may need to manually move operations around or break things into multiple migrations.
  6. Clean Builds Are Magic Sometimes migrations “fail” due to lingering junk. Do a clean solution build before adding a new migration. If things are still weird, delete the bin and obj folders. It shouldn’t work, but it often does.

  7. dotnet ef database drop Is a Weapon and a Warning Yes, it clears everything. But double-check your connection string every time. Dropping the wrong database because you copied over appsettings.Production.json is a story you only want to hear—not live.

  8. Test Your Migration Before You Commit Especially if you’re in a team or preparing for deployment. Do it in a local test environment first. Migration files that work on one dev machine can sometimes explode on another.

If I’ve missed anything, it’s probably because I’ve already repressed it. EF Core migrations can be brilliant when they work and hellish when they don’t. These tips won’t make it fun—but they might save you from losing a whole afternoon to a missing Include() or a rogue null reference.

Live long and dotnet ef database update.

This post is licensed under CC BY 4.0 by the author.