Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

dotnet ef migrations automation: Detect changes for migrations

I use the following CLI for DB Migrations:

  1. dotnet ef migrations add <Name-of-Migration>
  2. dotnet ef database update

However, I am looking for a way for this to happen automatically: when a change in the Model is detected.

So far, I have been able to eliminate Step 2 by doing the following in Startup.cs:

 private void SetupDatabase(IApplicationBuilder app)
    {
        using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
        {
            var context = serviceScope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
            //Migate any pending changes:
            context.Database.Migrate();
        }
    }

This migrates any pending changes created by doing: dotnet ef migrations add <Name-of-Migration> but it does not add migration for any changes in the model. How do I automate this migrations add?

like image 893
tika Avatar asked Jul 16 '17 21:07

tika


2 Answers

Updated: It is possible to move the first step of generating a migration automatically from code, a design decision that I personally do not agree with. Its still not possible in your target EF7 as I originally said (it has been removed from EF7 it seems as mentioned in this SO post as well as on this blog post by a member of Microsoft EF team mentioned in comments by Ivan), but tested in EF6 after Martin reply. The second step can be automated as you also found out already so I wont reproduce it again.

The steps for the first step are as follows (in ASP.net MVC Web Application with EF6):

  1. In your project (which should already be running with some models and in a consistent state), go to package manager console and run Enable-Migrations –EnableAutomaticMigrations. If your application has single DB context, it has applied the changes there too.
  2. Now go to an existing model and add a new field there, e.g. public String TestField { get; set; }
  3. As code first automatic migrations are ON, you do not need to run Add-Migration command again (hopefully, as I point out in later part of this answer), you just run Update-Database and the DB should be updated allowing your application to run fine.

Why automatic model change monitoring to generate and update database automatically might backfire sometimes (in my humble opinion and from MSDN page):

  • Automatic migrations wont work in change of field renames, as per MSDN.
  • In case of primitive field types being added, the existing data will need to be considered and you should consider manual migrations in this scenario.
  • You can intersperse automatic and code-based migrations but this is not recommended in team development scenarios. If you are part of a team of developers that use source control you should either use purely automatic migrations or purely code-based migrations. Given the limitations of automatic migration MSDN recommends using code-based migrations in team environments.
  • Its good to confirm that a model change is deliberate and was not a result of some leftover code while changes were being made, something that can happen and automating the complete process might slip such changes to DB.
  • The migrations that get generated are not always optimized and/or fail due to some data constraints or similar issues and hence should be reviewed.
  • Even update database has timed out for us on production data in some cases when there was loads of data the migration was handling. We had to then manually run it remotely and restart the server.

The above might not apply to everyone, but thought should share the reason why I agree with design decision of not making the migration generation and application to DB automated.

Everyone considering to enable automatic migrations should for sure read MSDN page for more examples and shortcomings.

like image 93
Hassan Avatar answered Nov 20 '22 18:11

Hassan


Entity Framework 4.3 has introduced the Automated Migrations.

Although I agree with Hassan's answer stating that is might be very tricky, this option actually exists.

Here is a short resume:

  1. When you enable Migrations, you must provide a parameter in the Package Manager Console:

enable-migrations –EnableAutomaticMigration:$true

  1. A Configuration class will be automatically generated:

    public Configuration()
    {
        AutomaticMigrationsEnabled = true;
    
        //Set this parameter to true if you want to let auto-migration delete data when a property is removed from an entity.
        //Not setting this will result in an exception when migration should remove a column.
        AutomaticMigrationDataLossAllowed = true;
    }
    
  2. Set the DB Initializer in your Context class

    Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyDBContext, MyConfigurationClass>("MyConnectionString"));
    

And there you go, change your model and see the changes...

I'm still not sure I will use it though, as I want my database to change when I say so...

like image 6
Martin Verjans Avatar answered Nov 20 '22 17:11

Martin Verjans