3

I have an EF6 code first implementation with migrations enabled and a single initial migration. I created a method to programmatically run the migration that looks like the following:

public void RunMigration()
{
    var migrationConfiguration = new DataAccess.Migrations.Configuration();
    var migrator = new System.Data.Entity.Migrations.DbMigrator(migrationConfiguration);
    migrator.Update();
}

When I got to testing I have several configured connection strings in the App.config. My Question:

How do I tell the DbMigrator what connection string to use?

update: I suppose the catch is doing this without extending DbMigrator.

4
  • I guess it would also be useful for me to check out how EF7 is doing it, since I will have to reproduce this there soon too. Commented Dec 16, 2015 at 16:51
  • The connection is the same as the target DbContext. Commented Dec 16, 2015 at 16:52
  • Sure, but there is no exposed way of sending in the dbContext with a different connection. I found an internal constructor that would be usefull. Not sure what the reasoning for internalizing the following DbMigrator constructor was: internal DbMigrator(DbMigrationsConfiguration configuration, DbContext usersContext) It seems that there is no way to just use the class, I need to create a concrete implementation. Commented Dec 16, 2015 at 17:03
  • Now that I get into it, everything I want to use on DbMigrator is internal so extending the class seems like it was not meant to be. Commented Dec 16, 2015 at 17:17

5 Answers 5

3

I Use

var migrator = new DbMigrator(new DbMigrationsConfiguration { TargetDatabase = new DbConnectionInfo("MyConnectionStringHere")});
migrator.Update();
Sign up to request clarification or add additional context in comments.

Comments

2

So unless someone comes up with a better answer: In EF6 there is no working way as of EF 6.1.3 to specify runtime connection strings for programmatic database migrations. I think the only thing I can see is that I will need to generate an sql script and programmatically run it at time of database setup. The issue with this is that I either have to compile in the text or deploy it with the binary.

Comments

1

It looks like you would set migrationConfiguration.TargetDatabase to a DbConnectionInfo.

One of the constructors for DbConnectionInfo takes a connection string. See MSDN

It looks like the easiest way to actually use this is to modify your DataAccess.Migrations.Configuration class to use the constructor with connection string.

2 Comments

While that sounds straight forward. I still get the error that it cannot find the default named connection string.
I'll do some tests when I'm back in front of the computer tonight and see if I can get something working.
1

You can set dbConnectionInfo:

migrationConfiguration.TargetDatabase = new DbConnectionInfo(connectionString);

full code:

public void RunMigration(string connectionString)
{
    var migrationConfiguration = new DataAccess.Migrations.Configuration();
migrationConfiguration.TargetDatabase = new DbConnectionInfo(connectionString);
    var migrator = new System.Data.Entity.Migrations.DbMigrator(migrationConfiguration);
    migrator.Update();
}

Importan!: make sour you don't set connection name in dbContext initializer.

Comments

0

I recently needed to do this, my solution was to create a custom Configuration class. The full code base works perfectly for me.

    public class Configuration : DbMigrationsConfiguration<Context>
{
    public void Init()
    {
        AutomaticMigrationsEnabled = false;
        AutomaticMigrationDataLossAllowed = true;            
    }
    public Configuration()
    {
        Init();
    }

    protected override void Seed(Context 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.
    }
    public static void UpdateDatabase()
    {
        try
        {
            var config = new Configuration();
            UpdateDatabase(config);
        }
        catch (Exception ex)
        {
            logger.writeLog("UpdateDatabase", ex);
        }
    }

    public Configuration(DbConnectionInfo db)
    {
        Init();
        TargetDatabase = db;
    }
    public static void UpdateDatabase(DbConnectionInfo db)
    {
        try
        {
            var config = new Configuration(db);
            UpdateDatabase(config);
        }
        catch (Exception ex)
        {
            logger.writeLog("UpdateDatabase", ex);
        }
    }
    private static void UpdateDatabase(Configuration config)
    {
        var migrator = new DbMigrator(config);
        var pending = migrator.GetPendingMigrations();
        if (pending.Count() > 0)
            migrator.Update();
    }
}

}

This offers both a default that uses the connection string specified in the DataContext as well as option to pass the connection.

Default Call

Configuration.UpdateDatabase();

Override with passing connection info

var offlineCon = new System.Data.Entity.Infrastructure.DbConnectionInfo("connection string","provider");
Configuration.UpdateDatabase(offlineCon);

where connection string is your specific connection string and provider the data provider e.g. System.Data.SqlClient

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.