I have a custom DatabaseInitialiser which is below
///
/// Implements the IDatabaseInitializer to provide a custom database initialisation fo
This is my attempt at Db Initializer which combines both Migration initializer and the default Db Create one with seeding. (note: it's not ideal, more like a simple exercise but gives a solution to what you're asking here, mostly works - just check all the updates I made).
How to create initializer to create and migrate mysql database?
As for the why and how - to fully understand that I'd suggest you also consult the EF source code (that's new version but in many ways similar)
a) Db initializer gets called usually only once (per connection) - and when you try to access your 'model' for the first time (first query or similar). Put a breakpoint in your initializer to check.
So it's completely safe to put it within constructor (though I prefer it on startup somewhere, config also). It only gets called when it's needed to initialize (and the last one set is used), you shouldn't invoke it manually.
Anyhow, to force the initializer you can do the this.Database.Initialize(force: true);
For when switching connections see my post on problems
Code first custom connection string and migrations without using IDbContextFactory
b) If you create your own IDatabaseInitializer and you still want migrations to work side by side
You shouldn't just call DbMigrator from outside - as your custom initializer will miss on the whole 'db creation' (e.g. if you wish to seed or something - check my example above).
Both things are effectively 'initializers' - so you'd need to integrate them into one, that'd chain things in some way. Have in mind that order of execution is important (see above ex. for problems) - you should check for 'empty condition', then call DbMigrator, then do your own intialization. I used one initializer as a base class, and merged the other.
And if you just want to seed - you can use the migration Configuration, that's the simplest if plausible.
Is pretty 'open ended' and there is no single answer. Usually it works, but issues are expexted...
Migrations are 3 things (as I see it) - your code model/entities, your database/tables, and the __MigrationHistory system table in the Db. All 3 need to stay in sync. If you get 'out of sync', you can drop the migration table, recreate migrations (with a flag to keep existing db) and then move on as before - i.e. there are solutions for when with live data. For this see How to ignore a table/class in EF 4.3 migrations,
you'd need permissions to drop/create Db for when moving database,
make sure your connection is right (change in config - and in sync with your DbContext name or ctor),
keep it simple, don't do fancy things or switch connections from code (possible but has problems) etc.,
don't mix database / code versions - i.e. one code entities version - one database. If you want to share the same Db with different code versions (e.g. staging, production) - don't (multi-tenant solutions will be available in EF6 - e.g. this),
if you need to manually apply the database - generate the script via Update-Database - and apply that, don't do things manually or you'll get it wrong (the migration history table) - see this one,
...that's just to name the few. It is pretty stable and usable IMO - but if you follow the rules - and know what the limitations are.
class CreateAndMigrateDatabaseInitializer
: CreateDatabaseIfNotExists, IDatabaseInitializer
where TContext : DbContext
where TConfiguration : DbMigrationsConfiguration, new()
{
private readonly DbMigrationsConfiguration _configuration;
public CreateAndMigrateDatabaseInitializer()
{
_configuration = new TConfiguration();
}
public CreateAndMigrateDatabaseInitializer(string connection)
{
Contract.Requires(!string.IsNullOrEmpty(connection), "connection");
_configuration = new TConfiguration
{
TargetDatabase = new DbConnectionInfo(connection)
};
}
void IDatabaseInitializer.InitializeDatabase(TContext context)
{
var doseed = !context.Database.Exists();
// && new DatabaseTableChecker().AnyModelTableExists(context);
// check to see if to seed - we 'lack' the 'AnyModelTableExists'
// ...could be copied/done otherwise if needed...
var migrator = new DbMigrator(_configuration);
// if (doseed || !context.Database.CompatibleWithModel(false))
if (migrator.GetPendingMigrations().Any())
migrator.Update();
// move on with the 'CreateDatabaseIfNotExists' for the 'Seed'
base.InitializeDatabase(context);
if (doseed)
{
Seed(context);
context.SaveChanges();
}
}
protected override void Seed(TContext context)
{
}
}