36

I am facing a weird problem with code first migrations in Entity Framework version 5. Sometimes Update-Database fails due to pending changes but Add-Migration command only produces migrations with database changes already contained in the last migrations and the database is up-to-date. Therefore I'd expect the new migration to be empty.

How does Add-Migration detect what changes are due? It doesn't seem to use the database as a source.

Jan Deinhard
  • 19,645
  • 24
  • 81
  • 137

1 Answers1

61

A snapshot of the database model is saved along with every migration in a .resx file. When you add a new migration, EF compares the current database model (which is generated from your model classes and settings from your DbModelBuilder) with the last migration and determines a changes between them.

The problem you are describing can occur if your migrations are out of sync. It happens to us if two developers make two independent migrations and these migrations are later merged back to the default branch.

Example:

Developer 1

Migration AddColumnA

Developer 2

Migration AddColumnB

Merged version

Migration AddColumnA - database snapshot includes columnA

Migration AddColumnB - database snapshot includes columnB but not columnA

If you add another migration, the changes are determined against migration AddColumnB, that doesn't contain information about columnA. A workaround for this problem is to generate dummy migration (with empty Up and Down methods) just to have the correct database model snapshot in the last migration.

Merged version

Migration AddColumnA - database snapshot includes columnA

Migration AddColumnB - database snapshot includes columnB but not columnA

Migration Dummy - database snapshot with columnA and columnB

Lukas Kabrt
  • 5,441
  • 4
  • 43
  • 58
  • 2
    Very interesting. Is there a way to prevent that the migrations are created based on that resource file, so that the database is used as the reference? This is a serious drawback of the migrations in my opinion, as I really want to have EXPLICIT migration files instead of just the automatic migration but don't want to have numerous dummy migration files when working with multiple devs on the same codebase. – Rip-Off Oct 04 '13 at 08:37
  • 2
    IMHO there isn't a way to specify database as the reference. Instead of creating dummy migration, you can update to the first migration (AddColumnA) and then regenerate the second migration. Up and Down methods will remain same but database snapshot will be updated to the correct version and dummy migration won't be necessary. – Lukas Kabrt Oct 04 '13 at 09:08
  • Thanks for all the information, but switching between revisions for each merge is a lot more of a hassle than having "ugly"/empty merge migration files. At least if you do one or more merges each day. – Rip-Off Oct 04 '13 at 09:33
  • 1
    You will need to add a merge migration Add-Migration Merge –IgnoreChanges (for more details:https://msdn.microsoft.com/en-us/data/dn481501.aspx) – Lyubomir Velchev Sep 06 '16 at 14:53
  • 2
    4 years later, and still having these problems. Sigh. – Davor Aug 03 '17 at 14:14
  • @LukasKabrt tahnk you for explanation. What will we do after adding empty migration ? Shall we update-database again? And empty migration should stay in the project afterwards ? – Can Feb 09 '18 at 07:27
  • @LyubomirVelchev -IgnoreChanges doesn't work in ASP.NET Core. Do you know what to do in that case? – Endri Feb 26 '18 at 13:43
  • I've just had this problem happen despite the fact that I'm the only one on the project. I *did* switch my connection string from my dev db to my prod db recently, so maybe this has been the cause. Either way, I'm fine with a dummy migration in my migrations. It has worked well for me. Tnx. – Jay Dec 05 '19 at 11:05
  • great answer! the word **snapshot** should be highlighted here! my summary is: add a new migration (**to recreate the .resx snapshot**), remove Up/Down content, update database – Dmitry Karpenko Feb 03 '21 at 14:31