11

Sto utilizzando Entity Framework 4.3 Codice Prima con un inizializzatore database personalizzato come questo:Come posso disabilitare l'uso della tabella __MigrationHistory in Entity Framework 4.3 Code First?

public class MyContext : DbContext 
{ 
    public MyContext() 
    { 
     Database.SetInitializer(new MyContextInitializer()); 
    } 
} 

public class MyContextInitializer : CreateDatabaseIfNotExists<MyContext> 
{ 
    protected override void Seed(MyContext context) 
    { 
     // Add defaults to certain tables in the database 

     base.Seed(context); 
    } 
} 

Ogni volta che il mio modello cambia, ho modificare il mio POCO e di mappature manualmente e aggiornare il mio database manualmente.

Quando eseguo di nuovo la mia domanda, ottengo questo errore:

Server Error in '/' Application.

The model backing the 'MyContext' context has changed since the database was created. Consider using Code First Migrations to update the database (http://go.microsoft.com/fwlink/?LinkId=238269).

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.InvalidOperationException: The model backing the 'MyContext' context has changed since the database was created. Consider using Code First Migrations to update the database (http://go.microsoft.com/fwlink/?LinkId=238269).

Utilizzando EFProfiler, ho anche notato queste query in corso di esecuzione:

-- statement #1 
SELECT [GroupBy1].[A1] AS [C1] 
FROM (SELECT COUNT(1) AS [A1] 
     FROM [dbo].[__MigrationHistory] AS [Extent1]) AS [GroupBy1] 

-- statement #2 
SELECT TOP (1) [Project1].[C1]   AS [C1], 
       [Project1].[MigrationId] AS [MigrationId], 
       [Project1].[Model]  AS [Model] 
FROM (SELECT [Extent1].[MigrationId] AS [MigrationId], 
       [Extent1].[CreatedOn] AS [CreatedOn], 
       [Extent1].[Model]  AS [Model], 
       1      AS [C1] 
     FROM [dbo].[__MigrationHistory] AS [Extent1]) AS [Project1] 
ORDER BY [Project1].[CreatedOn] DESC 

Come posso evitare questo?

risposta

10

All'inizio ero sicuro che fosse perché si imposta l'inizializzatore di default nel ctor ma esaminando un po 'ho scoperto che l'inizializzatore non viene eseguito quando viene creato il contesto ma piuttosto quando si esegue una query/si aggiunge qualcosa per la prima volta .

L'inizializzatore fornito controlla la compatibilità del modello in modo da non avere fortuna con loro. Si può facilmente rendere il proprio inizializzazione in questo modo invece però:

public class Initializer : IDatabaseInitializer<Context> 
    { 

     public void InitializeDatabase(Context context) 
     { 
      if (!context.Database.Exists()) 
      { 
       context.Database.Create(); 
       Seed(context); 
       context.SaveChanges(); 
      } 
     } 

     private void Seed(Context context) 
     { 
      throw new NotImplementedException(); 
     } 
    } 

che non dovrebbe controllare compatibilita e se il database non è presente sarà crearla.

UPDATE: "Contesto" dovrebbe essere il tipo di implementazione di DbContext

+0

Grazie, Mikael. La tua soluzione sembra funzionare. Sei positivo il predefinito 'CreateDatabaseIfNotExists' non fa altro che' if (! Context.Database.Exists()) {context.Database.Create(); Seed (contesto); } '? –

+0

Non sono sicuro, ma nel caso in cui non esista db generano esattamente lo stesso sql secondo Sql Profiler almeno. –

+0

Ho appena decompilato EntityFramework.dll per vedere cosa fa. Date un'occhiata a questo gist: https://gist.github.com/3017384 La parte mancante più importante è 'context.SaveChanges();' dopo aver chiamato 'Seed (context);'. Grazie per avermi indicato nella giusta direzione! –

Problemi correlati