Mysql
 sql >> база данни >  >> RDS >> Mysql

Как да създам инициализатор за създаване и мигриране на mysql база данни?

Мисля, че сте почти там - можете да потърсите изходния код за 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... прави вътре (това извикване, което не можем да извикаме), или нещо друго.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Излишно ли е съхраняването на броя на записите в базата данни?

  2. MySQL преобразува стойностите на моите времеви марки в 0000-00-00

  3. MySQL GROUP BY две колони

  4. MySQL5.6 заседна в процеса, опитвайки се да стартира услугата

  5. MySQL вмъкване от текстова област в множество редове