8

In primo luogo, ho letto queste domande/risposte:Impossibile eseguire la migrazione EF5 con database esistente

Questi tutti sembrano essere per EF versioni precedenti a EF5 e la mia situazione non sembra corrispondere a queste risposte. Quindi, permettimi di descrivere la mia situazione.

  1. La mia applicazione è stata originariamente creata utilizzando EF4, il primo modello. Ho progettato il mio database con il designer della GUI e l'ho usato per generare il mio database.
  2. Ho eseguito e raccolto dati nel database per alcuni mesi. Non posso davvero perdere questi dati.
  3. Ho ramificato il mio codice, ho installato EF5 con NuGet e ho utilizzato EF Power Tools per generare il mio modello dal mio database facendo clic con il pulsante destro del mouse su un nuovo progetto di libreria di classi e selezionando Entity Framework | Reverse engineer code first.
  4. Sono stato in grado di ri-riferire facilmente al mio nuovo progetto, convertire il mio progetto per utilizzare il nuovo DbContext invece di ObjectContext e rimosso la libreria di classi EF4 che conteneva il mio vecchio modello. Il programma funziona alla grande!

Ora, voglio provare le migrazioni automatiche, con cui ho avuto un po 'di esperienza in Ruby on Rails. Ecco cosa ho fatto:

  1. Ran Enable-Migrations. Ho avuto un po 'di problemi a causa delle stringhe di connessione e di quale app.config si stava abituando, ma alla fine l'ho presa. Tuttavia, this MSDN page dice che questo dovrebbe aver generato automaticamente la prima migrazione per farmi arrivare al punto in cui mi trovo già. Non è stato così.
  2. Ran Add-Migration InitialSchema per eseguire ciò che non è stato eseguito automaticamente nel passaggio 1. Ciò ha funzionato.
  3. Aggiunto un immobile ad uno dei miei oggetti del modello, poi tentato di eseguire Add-Migration AddSerialToLogEntries, e stato presentato con:

Impossibile generare una migrazione esplicita, perché i seguenti migrazioni esplicite sono in attesa: [201307190100268_InitialSchema] . Applicare le migrazioni esplicite in sospeso prima di tentare di generare una nuova migrazione esplicita .

Tentativo di applicare la migrazione sul mio database esistente non riuscito, il che non è sorprendente.

Le altre risposte di cui sopra hanno sostanzialmente affermato che sono sfortunato, ma come ho detto quelle erano per versioni precedenti di Entity Framework. Ho qualche opzione qui?

Mentre scrivevo questa domanda, pensavo di poter utilizzare SQL Server Management Studio per esportare i miei dati in uno script SQL, eliminare l'intero database, lasciare che EF lo creasse, quindi eseguire gli script per riavere i miei dati in ... lo proverò domani quando avrò tempo, ma mi piacerebbe sapere se ci sono altre opzioni in quanto non sono sicuro al 100% che funzionerebbe e detesterei avere errori nei dati inseriti nel processo.

risposta

12

Ran Enable-Migrations. Ha avuto un po 'di problemi a causa delle stringhe di connessione e di quale app.config si stava abituando, ma alla fine l'ha presa. Comunque, questa pagina MSDN dice che questo dovrebbe aver generato automaticamente la prima migrazione di per farmi arrivare al punto in cui mi trovo già. Non è stato così.

Ran Add-Migration InitialSchema per eseguire ciò che non era eseguito automaticamente al passaggio 1. Ciò ha funzionato.

Infatti il ​​comando enable-migrations crea una migrazione iniziale solo se il database è già stato creato con Codice-First, prima, nel qual caso il database contiene una tabella __MigrationHistory. Se questa tabella non esiste (che è il caso in cui si dispone di un database esistente che non è mai stato creato prima con Code-First) enable-migrations crea solo la classe Configuration. Devi chiamare manualmente add-migration per creare la prima classe di migrazione. Quindi, il comportamento che hai visto è previsto.

In genere, la procedura per preparare un database esistente per le migrazioni è la seguente se si utilizza EF 5:

  • chiamata enable-migrations nella console di gestione dei pacchetti. Una cartella Migrations nel progetto e una classe Configuration verrà creata.

  • Aprire la classe Configuration e impostare AutomaticMigrationsEnabled = false nel costruttore (se non lo è già per impostazione predefinita).

  • nel gestore dei pacchetti console chiamata

    add-migration -IgnoreChanges InitialSchema 
    

    "InitialSchema" è solo un nome di esempio. Puoi chiamarlo come vuoi. Verrà creata una classe <Timestamp>_InitialSchema che deriva da DbMigration. I metodi Up e Down in questa classe sono vuoti a causa del flag -IgnoreChanges. Senza questo flag la classe conterrebbe una migrazione per aggiungere l'intero modello al database che non è ciò che si desidera poiché il database esistente contiene già lo schema del database.

  • Eseguire update-database nella console di gestione pacchetti. Poiché il metodo Up è vuoto, questo aggiornamento non fa nulla con lo schema esistente eccetto crea la tabella __MigrationHistory (come una tabella di sistema nel database) e aggiunge il primo record a questa tabella che contiene un hash del modello del modello EF corrente.

  • Ultimo passaggio facoltativo: se si preferisce lavorare con le migrazioni automatiche, aprire la classe Configuration e impostare AutomaticMigrationsEnabled = true nel costruttore. Se si desidera procedere con le migrazioni basate su codice, lasciare la flag false.

A questo punto è possibile iniziare a modificare il modello. Ogni volta che crei una nuova migrazione con add-migration, questa sarà basata sul modello prima della modifica e la classe di migrazione conterrà solo le modifiche dello schema necessarie.

+0

Grande, risposta dettagliata. Proverò i tuoi passi il prima possibile. So che posso "annullare" enable-migrations semplicemente eliminando la cartella Migrations, ma posso semplicemente svuotare i metodi Up e Down della prima migrazione invece di cancellarla e ricominciare da capo? – Steve

+0

@Steve: Sì, dovrebbe funzionare altrettanto bene. – Slauma

+0

Ha funzionato alla grande, grazie! – Steve

3

vorrei suggerire un approccio leggermente diverso che vi lascerà in uno stato in cui è possibile utilizzare le migrazioni per creare database da zero nel proprio ambiente di sviluppo:

  1. Invece di chiamare add-migration -IgnoreChanges InitialSchema, cerca di ottenere il generazione della migrazione dello schema iniziale al lavoro. Come dici tu, questo dovrebbe succedere quando inizialmente hai chiamato Enable-Migrations. Potresti provare a puntare la tua connessione al database in un database inesistente per farlo funzionare.

  2. Come risultato di ciò, la migrazione InitialSchema conterrà la logica per creare il database come lo era nel punto in cui si reverse-engineering di esso. È necessario commentare i contenuti di Up() e Down() finché non si è distribuito in tutti gli ambienti che dispongono già di un database esistente.

  3. Quindi è possibile rimuovere il commento il contenuto di tali metodi e da allora in poi, nei vostri ambienti di sviluppo è possibile eliminare i database e ricrearli utilizzando

    var migrator = new DbMigrator(new Configuration()); 
    migrator.Update(); 
    

    e avrete la serie completa di migrazioni nella tabella __MigrationHistory . Questo è importante perché senza di esso non sarà possibile aggiungere nuove migrazioni in futuro.