2010-08-23 12 views
47

Ho creato un POCO "Solo codice" per l'utilizzo su un database esistente utilizzando Entity Framework 4 e CTP4. Quando eseguo una query ottengo l'erroreSolo codice quadro entità errore: il modello di backup del contesto è cambiato da quando il database è stato creato

The model backing the 'xyzContext' context has changed since the database was created. Either manually delete/update the database, or call Database.SetInitializer with an IDatabaseInitializer instance. For example, the RecreateDatabaseIfModelChanges strategy will automatically delete and recreate the database, and optionally seed it with new data.

Non sono chiaro perché questo sta accadendo o cosa posso cambiare. Ho semplicemente creato il POCO, definito un semplice DbContext, apportato alcune modifiche e quindi ho provato a eseguire una query semplice. Dal momento che sto usando "Solo codice", non sono a conoscenza di eventuali impostazioni di configurazione che devono essere fatte. E certamente non voglio ricreare o cancellare il database poiché si tratta di un database esistente.

Grazie per qualsiasi idea.

risposta

72

Ho trovato la risposta nei commenti su questo post sul blog di Scott Guthrie.

http://weblogs.asp.net/scottgu/archive/2010/08/03/using-ef-code-first-with-an-existing-database.aspx

For those who are seeing this exception:

"The model backing the 'Production' context has changed since the database was created. Either manually delete/update the database, or call Database.SetInitializer with an IDatabaseInitializer instance."

Here is what is going on and what to do about it:

When a model is first created, we run a DatabaseInitializer to do things like create the database if it's not there or add seed data. The default DatabaseInitializer tries to compare the database schema needed to use the model with a hash of the schema stored in an EdmMetadata table that is created with a database (when Code First is the one creating the database). Existing databases won’t have the EdmMetadata table and so won’t have the hash…and the implementation today will throw if that table is missing. We'll work on changing this behavior before we ship the fial version since it is the default. Until then, existing databases do not generally need any database initializer so it can be turned off for your context type by calling:

Database.SetInitializer<Production>(null); 
+4

Ho appena avuto lo stesso identico problema nel 2013 con EF5 corretto dalla tua risposta.Quindi non l'hanno risolto per una buona ragione, c'è un nuovo modello per EF5? – rism

+2

FYI ha avuto lo stesso problema con EF6, che era sorprendente. Questa risposta ha risolto il mio problema (tabelle integrate di identità generate da asp.net in cima al mio database SQL Server preesistente). – Rachael

+3

Utilizzando EF6, ho appena aggiornato il database a mano e ho abbandonato la tabella di migrazione. –

30

Si tratta di un bug nel CTP4 per l'utilizzo di EF con i database pre-esistenti.

È possibile risolvere il problema chiamando:

Database.SetInitializer<YourContext>(null); 

nel metodo Application Start di Global.asax

+0

Sto utilizzando MVC3. Ho aggiunto una colonna in più alla classe del modello. Ho anche inserito il tuo codice all'interno di global.asax. Tuttavia sto ancora ricevendo l'errore. Non penso che il vecchio db venga abbandonato o ricreato. Come posso aggiungere una nuova colonna al modello e rilasciare e ricreare il db? – bonCodigo

+0

'Application_Start vuoto protetta()' ' {' ​​' Database.SetInitializer (null);' ' AreaRegistration.RegisterAllAreas();' ' RegisterGlobalFilters (GlobalFilters.Filters);' 'RegisterRoutes (RouteTable.Routes);' '}' – bonCodigo

+0

Downvoted perché la domanda non è una domanda asp.net –

13

ho commentato in precedenza e ha funzionato nel momento in cui ho solo giocare con EF5 per me stesso con familarise è il funzionamento. Ora sto scrivendo il codice "effettivo" e mi sono allontanato dall'impostare un inizializzatore del database per il contesto nel codice a causa di un'architettura che ho scelto di utilizzare MEF per creare un'istanza di DbContext e iniettare tutte le dipendenze di configurazione come parti componibili.

Quindi, ancora una volta ho subito incontrato l'errore sopra descritto ma questa volta ho scelto di risolverlo utilizzando le voci del file di configurazione come di seguito.

<entityFramework> 
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework"> 
     <parameters> 
     <parameter value="v11.0" /> 
     </parameters> 
    </defaultConnectionFactory> 
    <contexts> 
     <context type="Basd.Erp.ContactContext, Basd.Erp" disableDatabaseInitialization="true"></context> 
    </contexts> 
    </entityFramework> 

Quindi impostando disableDatabaseInitialization = "true" nella sezione file di configurazione per EntityFramework si può superare l'errore descritto in precedenza e dal momento che non è nel codice uno dei vantaggi è la capacità di "più facilmente" uso astratta costruttori/fabbriche per creare il contesto.

+0

Ho ancora riscontrato questo problema in EF6 quando il mio contesto era in assembly separato. Questa è una buona risposta come @rism suggerito per soluzioni astratte 'n-tier'. – trevorc

3

Tutto quello che dovevo fare era far cadere il tavolo __MigrationHistory.

Contesto:

ho ricevuto questo errore quando ho cambiato il nome di una tabella. Dopo aver aggiunto l'annotazione [Table("NewTableName")] a uno dei miei modelli, Entity Framework ha generato una tabella __MigrationHistory.

0

Ho avuto lo stesso problema: aggiungere nuovamente la migrazione e aggiornare il database non ha funzionato e nessuna delle risposte precedenti sembrava corretta. Poi l'ispirazione mi ha colpito - sto usando più livelli (un web, un dato e un business). Il livello Web non ha mai generato questa eccezione: era il livello aziendale (che ho impostato come applicazione console per test e debug). Risulta che il livello aziendale non stava usando la giusta stringa di connessione per ottenere il db e creare il contesto. Così ho aggiunto la stringa di connessione alla configurazione dell'app e viola funziona. Mettetelo qui per gli altri che potrebbero incontrare lo stesso problema.

Problemi correlati