Мисля, че сте почти там - можете да потърсите изходния код за MigrateDatabaseToLatestVersion
(това е с отворен код http://entityframework.codeplex.com/
) - това е доста опростено, това, което прави, е да извика DbMigrator
- доколкото успях да видя.
Всичко, което трябва да направите, изглежда, е да обедините двете - да използвате едната или другата като основа, да добавите друга функционалност там - това трябва да работи добре според мен.
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)
{
}
}
наречете го така...
Database.SetInitializer(new CreateAndMigrateDatabaseInitializer<GumpDatabase, YourNamespace.Migrations.Configuration>());
...всъщност го заменете (тъй като е обща реализация), както правехте за CreateDatabaseIfNotExists
(просто имате допълнителен 'param' за конфигурация) - и просто предоставете 'Seed'.
class GumpDatabaseInitializer : CreateAndMigrateDatabaseInitializer<GumpDatabase, YourNamespace.Migrations.Configuration>
{
protected override void Seed(GumpDatabase context)
{
context.Database.ExecuteSqlCommand("CREATE UNIQUE INDEX Name ON Stations (Name)");
}
}
...и го наречете нещо като
Database.SetInitializer(new GumpDatabaseInitializer());
РЕДАКТИРАНЕ: Въз основа на коментарите - DbMigrator не трябва да се изпълнява два пъти. Той винаги проверява (прекарва малко време) и прави „празна“ актуализация и продължава напред. Но само в случай, че искате да премахнете това и да „проверете“ преди да влезете - това трябва да работи (променете подобно парче по-горе)...
var migrator = new DbMigrator(_configuration);
if (!context.Database.CompatibleWithModel(throwIfNoMetadata: false))
if (migrator.GetPendingMigrations().Any())
migrator.Update();
(това е излишна / двойна проверка - едно от if-s трябва да е достатъчно. Поставете прекъсване там - и вижте какво точно се случва, не трябва да влиза - след като Db се мигрира. Както споменах, работи добре, когато аз тествайте го.
РЕДАКТИРАНЕ:
Заменете вътрешността на InitializeDatabase
с...
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();
}
Това работи заобикалящо (половина) не-посяване - ако миграцията е първа. И миграциите трябва да са първи, в противен случай имате проблеми.
Все още трябва да го направите правилно - това е същността, ако не и всичко, от което може да се нуждаете - но ако има някакви проблеми с MySQL и т.н., вероятно още малко работа тук.
Забележка: Все още seeding не се обажда, ако имате db, но е празен. Проблемът е смесването на двата различни инициализатора. Така че ще трябва да решите това - или като внедрите това, което Create... прави вътре (това извикване, което не можем да извикаме), или нещо друго.