I am trying to write an easy to understand DBContext
class that takes a custom connection string, can run migrations, and that I allows me to generate migrations using Package Manager.
I seem to be going around in circles.
I have been able to get it working using code that feels awful to me. I documented this in my answer to This question on connection string and migrations.
Radek's answer looks much better than mine, but I find that when I implement it and then try and create a migration in Package Manager I get the message
The target context 'DataLayer.Context' is not constructible. Add a default constructor or provide an implementation of IDbContextFactory.
Where DataLayer.Context
is my context class.
I don't want to provide an implementation of IDbContextFactory
( and Radek's answer seems to indicate it isn't needed )
UPDATE:
I can generate a migration if I include a constructor with no parameter. For example
public Context() : base("ConnectionStringName") { }
For my context creation I pass the name of the connection string in app.config
public Context(string connString) : base(connString)
{
Database.SetInitializer(new CustomInitializer());
Database.Initialize(true);
}
At last I am able to both generate migrations, and run migrations for databases that the user selects.
HOWEVER:
When I drop the database and then run my app I have problems.
The initialiser code I am using, from the link above is
public class CustomInitializer : IDatabaseInitializer<Context>
{
public void InitializeDatabase(Context context)
{
try
{
if (!context.Database.Exists())
{
context.Database.Create();
}
else
{
if (!context.Database.CompatibleWithModel(false))
{
var configuration = new Configuration();
var migrator = new DbMigrator(configuration);
migrator.Configuration.TargetDatabase =
new DbConnectionInfo(context.Database.Connection.ConnectionString);
IEnumerable<string> migrations = migrator.GetPendingMigrations();
foreach (string migration in migrations)
{
var scriptor = new MigratorScriptingDecorator(migrator);
string script = scriptor.ScriptUpdate(null, migration);
context.Database.ExecuteSqlCommand(script);
}
}
}
}
catch (Exception ex)
{
}
}
}
When I drop the database a new one gets created but it has no tables. That would be because my table creation code is all in my first migration.
So the code inside the !context.Database.CompatibleWithModel(false)
condition does not run.
However alas, the code also does not run the second time around when it should have the metadatamodel.
Now to try and get the migration running...
SADNESS: No with Radek's custom initializer so far.
From NSGaga's comments I have resorted to exiting the application if I change connection.
var master = new myMDIForm();
master.ConnectionType = connectionType; // being an enum of the different connection names in app.config
while (master.ConnectionType != ConnectionType.None )
{
Application.Run(master);
}
See Question&Answers more detail:
os