sql >> Databasteknik >  >> RDS >> Mysql

Hur skapar man initializer för att skapa och migrera mysql-databas?

Jag tror att du är ganska där - du kan slå upp källkoden för MigrateDatabaseToLatestVersion (det är öppen källkod http://entityframework.codeplex.com/ ) - det är ganska förenklat, vad det gör är att kalla DbMigrator - så långt jag kunde se.

Allt du behöver göra verkar vara att slå samman de två - använd det ena eller det andra som grund, lägg till annan funktionalitet där - det borde fungera bra tycker jag.

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

kalla det så här...

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

...faktiskt åsidosätt det (eftersom det är en generisk implementering) som du gjorde för CreateDatabaseIfNotExists (du har bara extra 'param' för konfiguration) - och anger bara 'Seed'.

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

...och kalla det något som

Database.SetInitializer(new GumpDatabaseInitializer());

EDIT: Baserat på kommentarerna - DbMigrator bör inte köras två gånger. Den kollar alltid (förbrukar lite tid) och gör en "tom" uppdatering och går vidare. Men för säkerhets skull om du vill ta bort det och "kontrollera" innan du går in - detta borde fungera (ändra liknande bit ovan)...

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

(det här är en redundant / dubbelkoll - ett av om-en borde räcka. Lägg en paus där - och se exakt vad som händer, det ska inte komma in - när Db väl har migrerats. Som jag nämnde, fungerar det bra när jag testa det.

EDIT:

Byt ut insidan av InitializeDatabase med...

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

Detta fungerar runt (halvvägs) icke-sådd - om migreringen går först. Och migrationer måste vara först, annars har du problem.

Du måste fortfarande göra det ordentligt - detta är kärnan om inte allt du kan behöva - men om några problem med MySQL etc., förmodligen lite mer benarbete här.

Obs! Seedning ringer fortfarande inte om du har en db, men den är tom. Problemet är att blanda de två olika initialiseringarna. Så du måste reda ut det - antingen genom att implementera vad Create... gör inuti (det samtalet kan vi inte ringa) eller något annat.



  1. Gruppera OHLC-Stockmarket Data i flera tidsramar - Mysql

  2. Hur får man tillgång till Oracle-databasen över nätverket?

  3. På uppgraderingsmetoden anropas inte i android sqlite

  4. Bästa motsvarigheten för IsInteger i SQL Server