Myslím, že jste tam skoro – můžete vyhledat zdrojový kód pro MigrateDatabaseToLatestVersion
(je to open source http://entityframework.codeplex.com/
) – je to docela zjednodušující, do značné míry to dělá volání DbMigrator
- pokud jsem viděl.
Zdá se, že vše, co musíte udělat, je sloučit tyto dva - použít jeden nebo druhý jako základ, přidat tam další funkce - to by podle mě mělo fungovat dobře.
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)
{
}
}
nazvěte to takto...
Database.SetInitializer(new CreateAndMigrateDatabaseInitializer<GumpDatabase, YourNamespace.Migrations.Configuration>());
...ve skutečnosti to přepište (protože jde o obecnou implementaci), jako jste to dělali pro CreateDatabaseIfNotExists
(máte jen extra 'param' pro konfiguraci) - a stačí dodat 'Seed'.
class GumpDatabaseInitializer : CreateAndMigrateDatabaseInitializer<GumpDatabase, YourNamespace.Migrations.Configuration>
{
protected override void Seed(GumpDatabase context)
{
context.Database.ExecuteSqlCommand("CREATE UNIQUE INDEX Name ON Stations (Name)");
}
}
...a nazvěte to nějak jako
Database.SetInitializer(new GumpDatabaseInitializer());
UPRAVIT: Na základě komentářů - DbMigrator by neměl běžet dvakrát. Vždy to zkontroluje (stráví trochu času) a provede „prázdnou“ aktualizaci a pokračuje dál. Nicméně pro případ, že byste to chtěli odstranit a před zadáním „zkontrolovat“ – mělo by to fungovat (změňte podobný kus výše)...
var migrator = new DbMigrator(_configuration);
if (!context.Database.CompatibleWithModel(throwIfNoMetadata: false))
if (migrator.GetPendingMigrations().Any())
migrator.Update();
(toto je redundantní / dvojitá kontrola - jedno z if-s by mělo stačit. Dejte tam přestávku - a uvidíte, co se přesně děje, nemělo by se to dostat dovnitř - jakmile je Db migrován. Jak jsem zmínil, funguje dobře, když otestujte to.
UPRAVIT:
Nahraďte vnitřek InitializeDatabase
s...
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();
}
Toto funguje kolem (napůl) nezasévání – pokud migrace proběhne jako první. A migrace musí být na prvním místě, jinak máte problémy.
Stále to musíte dělat správně - toto je podstata, pokud ne vše, co byste mohli potřebovat - ale pokud se vyskytnou nějaké problémy s MySQL atd., pravděpodobně zde bude ještě nějaká práce.
Poznámka: Still seeding nevolá, pokud máte db, ale je prázdný. Problém je smíchání dvou různých inicializátorů. Takže to budete muset vyřešit - buď implementací toho, co Create... dělá uvnitř (to volání nemůžeme zavolat), nebo něčím jiným.