2015-11-04 10 views
21

Ho aggiunto una nuova proprietà nel mio modello esistente. È una proprietà bool con il valore predefinito true. Ci sono dati esistenti in questa tabella e vorrei impostare la nuova proprietà di una riga specifica su false right dopo aver creato il nuovo campo, nel metodo Up.Modifica dati nel metodo di migrazione Up - Entity Framework

public override void Up() 
    { 
     AddColumn("dbo.RequestValidationErrors", "IsBreaking", c => c.Boolean(nullable: false)); 
     using (Context ctx = new Context()) 
     { 
      var validation = ctx.RequestValidationErrorSet.FirstOrDefault(x => x.WordCode == "RequestValidationError.MoreThanOneItemFound"); 
      if (validation != null) 
      { 
       validation.IsBreaking = false; 
       ctx.SaveChanges(); 
      } 
     } 
    } 

In questo modo EF genera un errore durante dicendo

System.InvalidOperationException: Il modello di sostegno del contesto 'DbContext' è cambiato da quando il database è stato creato. Considerare l'utilizzo di Code First Migrations per aggiornare il database

È possibile modificare qui il database o devo farlo altrove?

risposta

27

Nel mezzo di una migrazione, è meglio utilizzare il metodo Sql() per aggiornare i dati del database.

Sql("UPDATE dbo.RequestValidationErrors SET IsBreaking = 0 WHERE WordCode = 'RequestValidationError.MoreThanOneItemFound'"); 

Inoltre, è necessario definire il valore predefinito per la nuova colonna. Quindi la soluzione dovrebbe essere qualcosa di simile:

public override void Up() 
{ 
    AddColumn("dbo.RequestValidationErrors", "IsBreaking", c => c.Boolean(nullable: false, default: true)); 
    Sql("UPDATE dbo.RequestValidationErrors SET IsBreaking = 0 WHERE WordCode = \"RequestValidationError.MoreThanOneItemFound\""); 
} 

Utilizzando un DbContext nel mezzo della sua migrazione è molto ambiguo. Cosa ti aspetti dal contesto? Ha il dopo lo stato di migrazione nei suoi modelli, ma il database ha il prima dello stato di migrazione nelle tabelle. Quindi il modello e il database non corrispondono. Se continui a utilizzare il codice DbContext nel codice, disabilitare la verifica del modello potrebbe essere la soluzione. È possibile disattivare il controllo utilizzando il modello:

Database.SetInitializer<Log4ProContext>(null); 
+0

Grazie per la soluzione e dei dispersi defaultValue, anche. – Perrier

7

Se si desidera utilizzare il quadro di cambiamenti come questo, si dovrebbe separare le modifiche database da modifiche dei dati.

Creare una migrazione solo per le modifiche del database ed eseguirlo.

Quindi creare una nuova migrazione (i metodi Su() e Giù() saranno vuoti). Ora puoi creare un'istanza di DatabaseContext e non ci saranno errori. In questo modo è possibile utilizzare Framework per queste modifiche e implementare correttamente un metodo Down().

3

Scrivere datiMigrazioni per EF6 può essere un lavoro ingrato. Mettiamo insieme una biblioteca Sono solo open sourcing qui per gli altri da usare, che aggiunge a questa funzione mancante, promessa da lungo tempo, all'EF6. Basta scrivere le classi utilizzando query EF regolari ecc

https://github.com/b9chris/Brass9.Data