Search code examples
c#sql-serverentity-frameworkentity-framework-6ef-code-first

Entity Framework 6 update database programmatically no automatic migration


I am trying to build an application that can connect to an existing database (of another program), insert its own table structure and update it to its last migration. I'm using a code-first approach.

I am using views, functions and stored procedures, that are created and updated in manually written migrations, so automatic-migrations cannot be turned on. I tried that, and it straightup did not work any more.

I tried playing around with the DbMigrator, but calling the Update() method seems to be doing nothing, except throwing a lot of sqlerrors. The MigrateDatabaseToLatestVersion initializer seemed promising, because it actually updated the database, but afterwards my application refused to connect with the database, basically telling me to activate automatic-migrations.

So far the only way I could get the DB to work with is to type 'update-database' into the package manager console. Is there any way I can just call programmatically, whatever is called when I type 'update-database' into the package manager console?


Solution

  • The following combination works like a charm now:

    I have enabled migrations, but kept automatic-migrations turned off. (enable-migrations)

    I added several migrations, some with automatic content, some written manually. (add-migration {name})

    Within the Migrations folder, a Configuration was created, which I altered to look like this:

      internal sealed class Configuration : DbMigrationsConfiguration<MyDbContext>
    {
        public Configuration()
        {
          AutomaticMigrationsEnabled = false;
          AutomaticMigrationDataLossAllowed = false;
          ContextKey = "MyDbContext";
        }
    
        protected override void Seed(StratonLocalizerDatabase context)
        {
            //  This method will be called after migrating to the latest version.
    
            //  You can use the DbSet<T>.AddOrUpdate() helper extension method
            //  to avoid creating duplicate seed data.
        }
    }
    

    And the constructor for my DbContext looks like this:

        public class MyDbContext: DbContext
      {
        [Obsolete("This constructor should never be used directly, and is only needed to generate entityframework stuff. Connection string can be adapted as pleased.")]
        public MyDbContext() : base(@"Server=MyServer\Instance;Database=MyDatabase;Trusted_Connection=True;")
        {
    
        }
    
        public MyDbContext(string connectionString) : base(connectionString)
        {
          Database.CreateIfNotExists();
          Database.SetInitializer(new MigrateDatabaseToLatestVersion<StratonLocalizerDatabase, Migrations.Configuration>());
          Database.Initialize(false);
        }
    

    The first constructor is only used to generate stuff and create migrations. For those actions an actual database is needed, so I just left the connection string for my database there.

    The second one is the one that should be used in the field, and it will update the database to the latest version, no matter if I ever connected to that DB before or if the db is just old. I have not yet tested if it will actually create a new database, if it does not exist, that is not my usecase, but I thought that might be helpful for you guys, so I kept the line in.

    Used Entity Framework version: EF6, NuGet package version 6.4.0 with EntityFrameworkExtras.EF6, NuGet package version 1.0.0