EF Core automatic migration

In our way toward migrating an ASP.NET full framework application to ASP.NET Core 2.0 we encountered a significant change in EF Core 2.0 in comparison with EF 6.x.

 

EF 6.x

In EF 6.x we were tightly relying on automatic migrations in deployment operations. We never created or added a migration to the code-base. Instead we had turned on automatic migration and allowed data loss. So when new versions of the project were deployed on the server, all necessary changes on the database were done behind the scenes automatically.

I know that enabling automatic migration on a production server is not a good idea. But it was a constraint forced by our deployment team.

Entity Framework Core
Entity Framework Core

EF Core

Automatic migration has been removed from EF Core. This feature is not present in EF Core 2.0. There is no plan to add this feature to EF. Microsoft thinks it benefits is less than its drawbacks.

There are 2 methods in EF Core 2.0 related to migration. Database.Migrate() and Database.EnsureCreated(). Neither of them are a complete migration.

Migrate() does not add or create a migration. It only checks if any not-applied migrations exists or not. If yes, then updates the database based on them.

EnsureCreated() creates the database based on the models in the project. But it does not do this in the migration way. Actually no migrations are needed by this method. Disadvantage of this method is that a database created by it, can not be updated in future by any migrations. Indeed this method is added to EF to help people create projects fast in MVP style.

Conclusion

At the end, we decided to not having automatic migrations as EF 6.x. Everyone that creates a model is responsible to create migrations too. And never call EF command in the production server to update the database. Instead call the Migrate() method on each startup to take the database to the latest available migration.

A sample code would be like this:

 

Sample code inspired from here.

EF Migration History not working

In our team we have developers working on same base code that uses EF Code First. All base codes are connected to same database and automatic migration is enabled. Time by time we get errors while running the application. Because some developer may be in past or forward in Model histories. In the other hand developer A may have been added Field AA to table T and developer B may have been added Field BB to table T. This may cause automatic migration to get in trouble. With some errors like table “ABC” exists before.

 

Today we get a similar error titled:

There is already an object named 'AspNetRoles' in the database.

 

My first guess was that is is caused by simultaneous but incompatible changes by developers. So checked source control history to see if anything strange has been happened or not. Found nothing unusual. As I had no clue I tried to understand values stored in __MigrationHistory table. It seemed that filed Model is data related to application model changes. It is a long data stored as binary. Googling showed me that my guess is true. I found a good article about it. It showed how to decode this data and extract human readable information from it. That was interesting. This data is in EDMX xml format. Yes EF Code First uses EDMX too but just hides it from scenes. BTW nothing in EDMX was unusual too.

 

I noticed that format of data in __MigrationHistory has been changed. All digits have been converted to Unicode Persian digits. Consequently I recalled that a colleague had run a T-SQL script on the database so all Arabic characters be converted to Persian characters. This is necessary specially when regarding Persian YEH and KEH characters. We rolled back this process in table __MigrationHistory and run the application once again. It worked again and there is no sign of EF migration problems. All the problem was caused by modifications in the __MigrationHistory table.