2013-07-29 11 views
20

Sto lavorando con le migrazioni di codice di Entity Framework 5.0 First e sto avendo un problema con l'esecuzione di Update-Database. Dice che ci sono cambiamenti di modello in sospeso; ma dovrebbe essere up-to-date, in modo da eseguireAggiornamento del database non riuscito a causa di modifiche in sospeso, ma Add-Migration crea una migrazione duplicata

Add-Migration SomeMigrationName 

e crea un file ... tuttavia, si crea un file che è essenzialmente lo stesso un duplicato di una precedente migrazione (se cerco di Update-Database di nuovo su quel file, fallisce con problemi relativi al tentativo di eliminare un vincolo inesistente). Inoltre, sono stato in grado di confermare che la migrazione "originale" è stata eseguita in base al modello di dati nel DB e dalla presenza di un record nella tabella __MigrationHistory!

Se elimino l'intero database ed eseguo di nuovo tutte le migrazioni, automaticamente o manualmente, ho lo stesso problema.

Il file di migrazione 'originale' che ho avuto è la seguente:

public partial class RenameLinkColumns : DbMigration 
{ 
    public override void Up() 
    { 
     DropForeignKey("dbo.Listing", "OfferedByUserId", "dbo.User"); 
     DropIndex("dbo.Listing", new[] { "OfferedByUserId" }); 
     AddColumn("dbo.Listing", "ListedByUserId", c => c.Int(nullable: false)); 
     AddForeignKey("dbo.Listing", "ListedByUserId", "dbo.User", "UserId", cascadeDelete: true); 
     CreateIndex("dbo.Listing", "ListedByUserId"); 
     DropColumn("dbo.Listing", "OfferedByUserId"); 
    } 

    public override void Down() 
    { 
     AddColumn("dbo.Listing", "OfferedByUserId", c => c.Int(nullable: false)); 
     DropIndex("dbo.Listing", new[] { "ListedByUserId" }); 
     DropForeignKey("dbo.Listing", "ListedByUserId", "dbo.User"); 
     DropColumn("dbo.Listing", "ListedByUserId"); 
     CreateIndex("dbo.Listing", "OfferedByUserId"); 
     AddForeignKey("dbo.Listing", "OfferedByUserId", "dbo.User", "UserId", cascadeDelete: true); 
    } 
} 

Quando ho fatto funzionare ancora una volta che Add-migrazione, i metodi Su/Giù in quel file sono esattamente gli stessi come queste.

Sono abbastanza impressionato dal fatto che le migrazioni siano state correttamente in grado di rilevare che avevo rinominato una colonna ForeignKey; ma è ciò che sta causando questo soffocare?

Sembra che ci sia una soluzione: ho eliminato il database e tutti i file di migrazione e ho creato una nuova migrazione "Iniziale", ma preferirei non farlo se possibile.

Update: Questo è stato non l'ultima migrazione che ha causato il problema, ma il problema è iniziato dopo una fusione (sto lavorando da solo, ma sto simulando il lavoro di squadra sui rami per saperne di più su git troppo), e cercando di ottenere il database al passo con l'unione. Questo potrebbe derivare dal collocare le migrazioni in un ordine particolare dopo l'unione, anche se una nota, le migrazioni hanno funzionato come come previsto nell'ordine in cui sono state eseguite quando ho fornito loro un DB vuoto.

Inoltre, questa migrazione originale necessitava di un ritocco manuale quando le tabelle contenevano i dati, poiché i dati dovevano essere copiati dalla vecchia alla nuova colonna. Tuttavia, ho provato quel file con e senza le mie modifiche manuali in quel file, e ho comunque riscontrato il comportamento osservato.

risposta

22

This answer explains why it happens. Per risolverlo, chiamo add-migration e lo denomino MERGE e quindi rimuovo qualsiasi codice di migrazione duplicato che è già accaduto. Questo è solo per aggiornare l'istantanea del modello per riflettere il modello unito.

Esempio:

public partial class MERGE : DbMigration 
{ 
    public override void Up() 
    { 
     // Intentionally left blank. 

     // This may seem like a hack, but it is necessary when using source control. 
     // When a migration is created via add-migration, EF creates 
     // an .edmx file from the current code first classes. It compares this .edmx to the .edmx stored in the last migration before this, 
     // which I'll call it's parent migration. The edmx snapshots are gzipped and stored in base64 in the resource files (.resx) if you 
     // want to see them. EF uses the difference between these two snapshots to determine what needs to be migrated. 

     // When using source control it will happen that two users add entities to the model independently. The generated edmx snapshots will 
     // only have the changes that they have made. When they merge in source control, they will end up with this: 

     // Migration      | Snapshot Contents 
     // -------------------------------- | ---------------- 
     // 20150101_Parent Migration  | A 
     // 20150102_Developer 1's Migration | A + Change 1 
     // 20150103_Developer 2's Migration | A + Change 2 

     // So calling add-migration will create the current snapshot edmx from the Code First model and compare it to the 
     // the latest migration's snapshot, which is A + Change 2, and see that Change 1 is missing. That is why it 
     // creates a duplicate migration. We know that the migrations have already been applied, so the only thing that this 
     // migration will do is update the current snapshot .edmx so that later migrations work fine. 
    } 

    public override void Down() 
    { 

    } 
} 

`` `

+0

Ciao Mike io non sono in grado di controllo incrociato la vostra risposta come il mio ambiente di sviluppo è ormai passata, ma acceptng come risposta, come ci avete fornito convincenti ragionamento (e un bel commento sulla migrazione sopra :) – Nij

+2

Grazie per aver spiegato questo. Avevo già pensato di farlo come una "correzione", ma non ero contento di controllarlo senza capire perché funzionasse. –

+2

questo funziona ma è orribile, non so cosa fare una migrazione nulla-fare ogni volta che ho un cambiamento di silicio –

3

Anche io lo vedo sempre. Non so perché, vorrei averlo fatto, ma la mia soluzione è fare un add-migration che farà un duplicato. Ora questo duplicato si apre nell'editor e quindi lo modifico, in modo che i metodi Su e Giù siano vuoti. Quindi il risultato è un file di migrazione che non fa nulla! VS è felice e si può fare il database di aggiornamento senza errori (fino alla prossima volta).

Spero che questo aiuta :)

0

ho appena affrontato lo stesso problema.

Una volta creata la migrazione. Ho provato ad aggiornare il database ed ho ricevuto il seguente messaggio:

Impossibile aggiornare il database che corrisponda al modello attuale, perché ci sono modifiche in sospeso e la migrazione automatica è disattivata.Scrivi le modifiche del modello in sospeso in una migrazione basata su codice o abilita la migrazione automatica . Impostare DbMigrationsConfiguration.AutomaticMigrationsEnabled su true per abilitare la migrazione automatica. È possibile utilizzare il comando Add-Migration per scrivere le modifiche del modello in sospeso a una migrazione basata su codice.

Quindi, ho generato nuovamente la migrazione ma è stato duplicato.

Il problema risolto quando i Crea il progetto dopo aver creato la migrazione. Quindi lo script Update-Database trova il metodo di migrazione e funziona. Almeno per il mio caso.

Problemi correlati