We've managed to get past the roadblock described below and are now able to drop columns with EF Migrations in a CD world. More information can be found here.
We've hit a roadblock with Entity Framework Migrations and our Continuous Deployment strategy and it doesn't look like there is a way forward without replacing it.
I've previously written about our blue / green deployment strategy on Azure and how we bypass the EF Migrations consistency check on application start-up. This was working well for us but problems arose when attempting to drop a column from the database.
The issue is caused by the following two features of Entity Framework:
- When selecting an entity from the database, EF quite rightly lists out each property from the model in the select statement. Something along the lines of
SELECT Id, FirstName, LastName, Email, DateOfBirth FROM [User];.
- Entity Framework Migrations forces you to add a migration when you add or remove properties from your model and will throw an error if it detects that a model is out of sync with the database*.
*Even though you can (and should) disable this check when deploying to a test or production environment, it is essential when working in a development team as you need to know if a migration has been added that is yet to run on your development database.
To illustrate our issue, let's assume that we have removed the DateOfBirth column from the User entity, added a migration and deployed the change into a Azure WebApp test environment using the following automated deployment process:
- Run the migration, dropping the specified columns
- Deploy the application into the staging slot
- Wait for the application to respond to ping requests
- Swap the staging slot with the production slot
As soon as the migration is run and the column is dropped from the database, the live version of the application is still running selects against a table with the now non-existant DateOfBirth column and will error.
This error will continue to persist until we hit step 4 in the process where the staging slot is swapped with the production slot. Depending on the complexity of your deployment process and the number of apps sharing the database being altered, this could cause significant downtime of your application.
For now, we're going to have to be very careful if/when we remove columns from the production database.
Looking forward, we have two options:
- Remove consistency checking in development, manually create migrations (rather than rely on the framework doing this for us) and regularly check to see if there are any pending migrations. This is option isn't preferred as EF Migrations is a right pain to work with (notably when working in a team greater than 1) and now just doesn't seem worth it.
- Move to another framework (and our preferred option)