Creo que ya está allí:puede buscar el código fuente para MigrateDatabaseToLatestVersion
(es de código abierto http://entityframework.codeplex.com/
) - es bastante simple, lo que hace es llamar al DbMigrator
- Por lo que pude ver.
Parece que todo lo que tiene que hacer es fusionar los dos:use uno u otro como base, agregue otra funcionalidad allí, creo que debería funcionar bien.
class CreateAndMigrateDatabaseInitializer<TContext, TConfiguration> : CreateDatabaseIfNotExists<TContext>, IDatabaseInitializer<TContext>
where TContext : DbContext
where TConfiguration : DbMigrationsConfiguration<TContext>, 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<TContext>.InitializeDatabase(TContext context)
{
Contract.Requires(context != null, "context");
var migrator = new DbMigrator(_configuration);
migrator.Update();
// move on with the 'CreateDatabaseIfNotExists' for the 'Seed'
base.InitializeDatabase(context);
}
protected override void Seed(TContext context)
{
}
}
llámalo así...
Database.SetInitializer(new CreateAndMigrateDatabaseInitializer<GumpDatabase, YourNamespace.Migrations.Configuration>());
... en realidad, anúlelo (ya que es una implementación genérica) como lo estaba haciendo para CreateDatabaseIfNotExists
(solo tiene un 'parámetro' adicional para la Configuración), y solo proporcione la 'Semilla'.
class GumpDatabaseInitializer : CreateAndMigrateDatabaseInitializer<GumpDatabase, YourNamespace.Migrations.Configuration>
{
protected override void Seed(GumpDatabase context)
{
context.Database.ExecuteSqlCommand("CREATE UNIQUE INDEX Name ON Stations (Name)");
}
}
...y llámalo algo como
Database.SetInitializer(new GumpDatabaseInitializer());
EDITAR: Según los comentarios, DbMigrator no debería ejecutarse dos veces. Siempre verifica (dedica un poco de tiempo) y realiza una actualización 'en blanco' y continúa. Sin embargo, por si acaso, si desea eliminar eso y 'verificar' antes de ingresar, esto debería funcionar (cambie la pieza similar anterior) ...
var migrator = new DbMigrator(_configuration);
if (!context.Database.CompatibleWithModel(throwIfNoMetadata: false))
if (migrator.GetPendingMigrations().Any())
migrator.Update();
(esta es una verificación redundante / doble:uno de los if-s debería ser suficiente. Ponga un descanso allí, y vea exactamente lo que está sucediendo, no debería ingresar, una vez que se migra Db. Como mencioné, funciona bien cuando pruébalo.
EDITAR:
Reemplace el interior de InitializeDatabase
con...
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(throwIfNoMetadata: false))
if (migrator.GetPendingMigrations().Any())
migrator.Update();
// move on with the 'CreateDatabaseIfNotExists' for the 'Seed'
base.InitializeDatabase(context);
if (doseed)
{
Seed(context);
context.SaveChanges();
}
Esto funciona alrededor de la no siembra (a medias), si la migración se realiza primero. Y las migraciones tienen que ser lo primero, de lo contrario tienes problemas.
Aún debe hacerlo correctamente; esta es la esencia, si no todo lo que podría necesitar, pero si hay algún problema con MySQL, etc., probablemente haya más trabajo de piernas aquí.