ygoe
ygoe

Reputation: 20414

Explicit automatic migration with Entity Framework

So I've managed to have some database tables created from my Entity Framework Code First model classes. After changing these model classes and running my code again, I got this exception:

System.Data.Entity.Migrations.Infrastructure.MigrationsException: The target context '...Context' is not constructible. Add a default constructor or provide an implementation of IDbContextFactory.

Unfortunately, the database connection parameters are determined at runtime, depending on a user selection. So there is no default or static connection string. A connection can only be established through code logic. Here's one of my numerous hacks I needed to use to make EF work for me:

// Manually create database connection because Entity Framework won't let me specify a
// provider name together with a connection string.
// Source: http://stackoverflow.com/a/17403462/143684
var conn = DbProviderFactories.GetFactory("Oracle.ManagedDataAccess.Client").CreateConnection();
conn.ConnectionString = "User Id=" + dbUserName + ";Password=" + dbPassword + ";Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=" + dbHostName + ")(PORT=" + dbPort + "))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=" + dbInstance + ")))";
var appContext = new AppContext(conn);

The only constructor for AppContext (my DbContext) takes a DbConnection parameter. A parameterless constructor for AppContext won't work because it wouldn't know where to connect to. Yet migrations want one from me.

I call this before the code shown above: (Configuration is the code that the PowerShell command generated for me.)

Database.SetInitializer(
    new MigrateDatabaseToLatestVersion<AppContext, Configuration>());

Can I somehow convince EF to run automatic migrations on the AppContext instance I create for it?

Upvotes: 1

Views: 567

Answers (1)

Paul
Paul

Reputation: 1264

Did you try implementing the IDbContextFactory interface?

public class CustomContextFactory : IDbContextFactory<AppContext>
{
    public AppContext Create()
    {
        return new AppContext(CustomDbConnection);
    }

    private DbConnection CustomDbConnection
    {
        get
        {
            // here goes your code to build a DbConnection
        }
    }
}

Upvotes: 1

Related Questions