9

I have a context in my database that points to 3 child database instances. I inject the correct db connection string via the context's construtor.

However I'm having difficulty getting this to work with automatic migrations. The issue is, automatic migrations expects a a parameterless constructor which I can't provide and IDbContextFactory only allows me to return one connection string.

Is there a way I can get the migration scripts to run against multiple databases or would I need to create 3 separate contexts?

6
  • Just to be clear, you're using one EF context to connect to 3 different instances of a database using the same Schema and you want the context to be able to maintain the upgrade path for all 3 instances? Commented Jul 20, 2015 at 11:53
  • Yeah exactly! When it tries to do the automatic migrations is seems to only allow me to specific a single connection string. Commented Jul 20, 2015 at 11:55
  • If what @Tr1stan is saying is correct, then how I deal with is public CustomContext() : base(DbConnections.GetCurrentConnectionString) { } What this does is your context will still have a parameterless constructor, but the connectionstring will depend on whatever criteria was setup previously (for me, the user selects dev, test, prod) Commented Jul 20, 2015 at 11:58
  • Are you using this in a separate application to maintain a set of databases/releases that are used by separate clients, all running the same Schema? Trying to get my head around why you'd want to do what you're doing...mainly because I'm nosy :) Commented Jul 20, 2015 at 13:57
  • @SpaceSteak Good thinking - I'll try and explore this. Commented Jul 20, 2015 at 15:38

1 Answer 1

6

Each instance of your context has one database connection.

Assuming that each child database wille have the same code-first model, you can launch one instance of the same context class for each database.

Just call DbContext.Initialize( true ) to migrate the database, then close the connection.

var context1 = new MigratorContext( connectionString1 );
context1.Initilialize( true );
var context2 = new MigratorContext( connectionString2 );
context2.Initilialize( true );
var context3 = new MigratorContext( connectionString3 );
context3.Initilialize( true );

Add a constructor for MigratorContext taking the connection string:

public MigratorContext(string connString)
   : base( connString)
{
    var migrationConfiguration = new MigrationConf();

    Database.SetInitializer<MigratorContext>(
        new MigrateDatabaseToLatestVersion<
            MigratorContext, MigrationConf>(true, migrationConfiguration));
}

public sealed class MigrationConf : DbMigrationsConfiguration<MigratorContext>
{
    public MigrationConf()
        : base()
    {
        AutomaticMigrationsEnabled = true;
        AutomaticMigrationDataLossAllowed = true;
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

Hmm that could work - Where would you recommend initializing the 3 dbcontexts in an MVC application?
It can be initialized at startup or when your application requires to use persistence. Those contexts are used by the controller, but the context depend on the model, so that could be a persistence layer between your controller layer and your model layer.
Apologies for the late response - I did managed to get this working so thank you for your help. The trick here is to set the MigrateDatabaseToLatestVersion useSuppliedContext to true otherwise it will expect an empty contructor.

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.