Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Jak stworzyć inicjator do tworzenia i migracji bazy danych mysql?

Myślę, że już tam jesteś — możesz wyszukać kod źródłowy dla MigrateDatabaseToLatestVersion (to open source http://entityframework.codeplex.com/ ) - to dość uproszczone, to, co robi, to wywołanie DbMigrator - o ile mogłem zobaczyć.

Wydaje się, że wszystko, co musisz zrobić, to połączyć te dwa - użyj jednego lub drugiego jako podstawy, dodaj tam inną funkcjonalność - myślę, że powinno to działać dobrze.

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)
    {
    }
}

nazwij to tak...

Database.SetInitializer(new CreateAndMigrateDatabaseInitializer<GumpDatabase, YourNamespace.Migrations.Configuration>());

...właściwie nadpisz go (ponieważ jest to ogólna implementacja), tak jak robiłeś to dla CreateDatabaseIfNotExists (po prostu masz dodatkowy 'param' dla konfiguracji) - i po prostu podaj 'Seed'.

class GumpDatabaseInitializer : CreateAndMigrateDatabaseInitializer<GumpDatabase, YourNamespace.Migrations.Configuration>
{
    protected override void Seed(GumpDatabase context)
    {
        context.Database.ExecuteSqlCommand("CREATE UNIQUE INDEX Name ON Stations (Name)");
    }
}

...i nazwij to mniej więcej

Database.SetInitializer(new GumpDatabaseInitializer());

EDYTUJ: Na podstawie komentarzy - DbMigrator nie powinien być uruchamiany dwukrotnie. Zawsze sprawdza (poświęca trochę czasu) i wykonuje „pustą” aktualizację i rusza dalej. Jednak na wszelki wypadek, jeśli chcesz to usunąć i „sprawdzić” przed wejściem - to powinno zadziałać (zmień podobny element powyżej)...

var migrator = new DbMigrator(_configuration);
if (!context.Database.CompatibleWithModel(throwIfNoMetadata: false))
    if (migrator.GetPendingMigrations().Any())
        migrator.Update();

(jest to nadmiarowe / podwójne sprawdzenie - jeden z if-s powinien wystarczyć. Umieść tam przerwę - i zobacz dokładnie, co się dzieje, nie powinno się dostać - po migracji Db. Jak wspomniałem, działa dobrze, gdy ja przetestuj to.

EDYTUJ:

Zastąp wnętrze InitializeDatabase z...

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();
}

Działa to w ramach (w połowie) nie-seedingu — jeśli migracja jest pierwsza. A migracje muszą być pierwsze, inaczej masz problemy.

Nadal musisz to zrobić poprawnie - to jest sedno, jeśli nie wszystko, czego możesz potrzebować - ale jeśli jakieś problemy z MySQL itp., prawdopodobnie trochę więcej działa tutaj.

Uwaga: Nadal seedowanie nie wywołuje, jeśli masz bazę danych, ale jest ona pusta. Problem polega na mieszaniu dwóch różnych inicjatorów. Musisz więc to rozpracować — albo implementując to, co Create… robi wewnątrz (tego wywołania nie możemy wywołać), albo coś innego.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak ustawić zmienną środowiskową Path za pomocą C#

  2. Zaznaczanie wszystkich elementów w jednej tabeli i łączenie z inną tabelą, pozwalając na wartości null

  3. Eksportuj dużą tabelę MySQL jako wiele mniejszych plików

  4. Nie można połączyć się z lokalnym serwerem MySQL w docker-compose

  5. MySQLi - deklarowanie zmiennej po bind_param?