2014-09-21 13 views
8

Ho la seguente situazione e non sono in grado di determinare la corretta strategia di migrazione. L'aiuto è apprezzatoEntity framework code first migration strategy with database esistente

  • applicazione crea e utilizza database come l'archiviazione dei dati
  • applicazione ha bisogno di aggiornare il database sulla start up se necessario
  • utilizzando Nuget console di Gestione non è un'opzione. (Fini della migrazione, a livello locale non è un problema)
  • I Have database in distribuzione che non sono EF

Ora voglio iniziare a utilizzare il primo approccio codice di EF esistente. Che cosa ho bisogno di realizzare è:

  1. Se nessun database quindi creare una
  2. Se database esiste l'uso di migrazione vuota (solo per essere pronto per i prossimi aggiornamenti)
  3. Questo dovrebbe avvenuto su richiesta avviare

database non esiste ====> Creare EF iniziale =====> Upg v1 =====> Upg V2

database esiste =====> Salta iniziale, ma essere pronti per prossimi aggiornamenti =====> Upg v1 ======> Upg v2

Grazie per il vostro aiuto

Informazioni aggiuntive: Questo è il database che esiste (solo un esempio):

CREATE DATABASE Test 
GO 

Use Test 
GO 
CREATE SCHEMA [TestSchema] AUTHORIZATION [dbo] 
GO 
CREATE TABLE [TestSchema].[Table1](
    [Id] [uniqueidentifier] NOT NULL, 
    [Column1] [nvarchar](500) NOT NULL, 
    [Column2] [bit] NOT NULL, 
    [Column3] [bit] NOT NULL, 
CONSTRAINT [PK_MonitorGroups] PRIMARY KEY CLUSTERED 
(
    [Id] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 
GO 

Usando il reverse engineering EF creato migrazione iniziale:

public partial class Initial : DbMigration 
    { 
     public override void Up() 
     { 
      CreateTable(
       "TestSchema.Table1", 
       c => new 
        { 
         Id = c.Guid(nullable: false), 
         Column1 = c.String(nullable: false, maxLength: 500), 
         Column2 = c.Boolean(nullable: false), 
         Column3 = c.Boolean(nullable: false), 
        }) 
       .PrimaryKey(t => t.Id); 
     } 

     public override void Down() 
     { 
      DropTable("TestSchema.Table1"); 
     } 
    } 

se uso il codice fornito da @spender su un database non esistente, tutto è bello . Se lo utilizzo su un database esistente funziona finché non modifico il modello (prossima migrazione).

Quello che ho visto è che lo script di aggiornamento restituito dalla migrazione contiene l'intera creazione del database. E non può essere eseguito contro oggetti già esistenti.

Ciò che può effettivamente funzionare è aggiungere la tabella di migrazione al database esistente e aggiungere i dati iniziali, ma non sono sicuro che questa sia una buona soluzione.

+0

Quindi vuoi lasciare che la comunità faccia funzionare il tuo progetto. –

+1

@Farhad no, ho solo bisogno di un piccolo aiuto :) – Adi

+0

Quindi va bene;) –

risposta

11

Questo mi è costato un bel po ', quindi sono felice di condividerlo qui.

Quindi per prima cosa è necessario decodificare il database. Entity framework power tools può farlo per te. Una volta installato, nel progetto, installare EF con nuget, fare clic con il tasto destro del mouse sul nodo del progetto in solution explorer, quindi su Entity Framework ->Reverse Engineer Code First. Questo genererà un sacco di classi di modelli e classi di mappatura per il tuo progetto.

successiva, in Console Gestione pacchetti

Enable-Migrations 

poi

Add-Migration Initial 

per creare una migrazione che descrive il passaggio da vuoto DB schema corrente.

Ora modificare il costruttore generato Configuration.cs classe:

public Configuration() 
    { 

     AutomaticMigrationsEnabled = false; 
     AutomaticMigrationDataLossAllowed = false; 
    } 

Successivamente, in fase di avvio applicazione, (quindi forse in global.asax Application_Start se si sta eseguendo da un server web), è necessario innescare migrazioni. Questo metodo farà il lavoro:

public static void ApplyDatabaseMigrations() 
    { 
     //Configuration is the class created by Enable-Migrations 
     DbMigrationsConfiguration dbMgConfig = new Configuration() 
     { 
      //DbContext subclass generated by EF power tools 
      ContextType = typeof(MyDbContext) 
     }; 
     using (var databaseContext = new MyDbContext()) 
     { 
      try 
      { 
       var database = databaseContext.Database; 
       var migrationConfiguration = dbMgConfig; 
       migrationConfiguration.TargetDatabase = 
        new DbConnectionInfo(database.Connection.ConnectionString, 
             "System.Data.SqlClient"); 
       var migrator = new DbMigrator(migrationConfiguration); 
       migrator.Update(); 
      } 
      catch (AutomaticDataLossException adle) 
      { 
       dbMgConfig.AutomaticMigrationDataLossAllowed = true; 
       var mg = new DbMigrator(dbMgConfig); 
       var scriptor = new MigratorScriptingDecorator(mg); 
       string script = scriptor.ScriptUpdate(null, null); 
       throw new Exception(adle.Message + " : " + script); 
      } 
     } 
    } 

Ora è possibile aggiungere più migrazioni normalmente. Quando l'app viene eseguita, se queste migrazioni non sono state applicate, verranno applicate quando viene chiamato il numero ApplyDatabaseMigrations.

Ora hai ragione nel primo codice EF. Penso che sia quello che hai chiesto, giusto?

+0

innanzitutto grazie per aver risposto. - Funziona bene se nessun database è presente - Se nel database del modello non sono presenti modifiche funzionanti (il contesto può essere inizializzato) - Ma apportare modifiche nel modello non aggiornerà il database esistente Modificherò la mia domanda per fornire più info – Adi

+0

Quando si modifica il modello, è necessario nuovamente "Aggiungi-Migrazione". Questo creerà la nuova migrazione che verrà applicata in primo piano sulle migrazioni precedenti – spender

+0

e supponiamo che tutti gli altri casi funzionino tranne questo: database creato da EF con 2 migrazioni Iniziale e V1 si applicano al database esistente. Il database esistente è identico a Initial e richiede solo V1 da applicare, ma la migrazione non lo rileva perché il db esistente non ha tabella di migrazione (non viene creato da EF). – Adi

Problemi correlati