The official Microsoft documentation for using Migrations in Team Environments covers the basics. However, they neglect to mention one very important thing:
Removing Migrations in a Team Environment Can Be Deadly!
Well, not deadly, but close. Once you have merged migrations from other team members, none of you can safely remove any of the merged migrations, nor can you remove the migration created following a merged migration!
The reason for this: The Migration.Designer.cs file for every migration essentially contains a copy of the current ModelSnapshot.cs file at the time of the creation of the migration. While the designer file is not used to create the model snapshot when the migration is created or applied, it IS used to restore the model snapshot when the migration is rolled back to.
For example: Dev 1 creates Migration A, and Dev 2 creates Migration B. The two migrations are merged into the same project, and the model snapshot file is successfully merged without any conflicts. If you follow the official Microsoft document (linked above), you’ll end up with two migrations successfully applied to your database, and your model snapshot file will include changes from both migrations. Then Dev 1 add a new migration (C), finds he made a mistake, and attempts to remove the migration. Entity Framework then restores the model snapshot file to match the contents of the designer file of the migration being restored (Migration B). But at the time when Migration B was created by Dev 2, he was working in an isolated branch and was not aware of Migration A, so Migration B’s designer file won’t contain changes that were included in Migration A. This essentially results in the model snapshot file being restored to what it was in Dev 2’s branch at the time he created Migration B.
Proposed Solution 1: Add New Baseline Migration After Merge
A viable solution to the issue would be to add a new milestone migration to the master branch after a merge has been completed, and all team members should receive it when they pull their changes from master into their own branches for the next leg of work. The milestone migration will include a proper Migration.Designer.cs file, which will contain all snapshot of all changes made in the previous merged migrations, giving you a correct ModelSnapshot file if a subsequent migration is deleted. The milestone migration should be named clearly, e.g. “Sprint7_Milestone”, or “Sprint7_NoTouchy”, etc. The milestone migration should never be removed.
Proposed Solution 2: Just Don’t Remove Migrations
Unless you’ve ended up with a migration that will actually fail when applied, it seems to be best practice to add new migrations with updates instead of removing a migration. This works around the merged migration issue. But when you DO have to remove a migration, you’ll have to whip out that razor blade and ninja some files back together if you’re dealing with merged migrations. So you’re probably better off going with Proposed Solution 1 in a team environment.