Più contesti database nello stesso database e applicazione in EF 6 e migrazioni Code First


94

Sono nuovo in Entity Framework. Sto provando a configurare un'applicazione MVC che utilizza EF 6. Sto usando le migrazioni Code First. Sto utilizzando le aree nell'app e vorrei avere diversi DbContext in ciascuna area per suddividerla. So che EF 6 ha ContextKey, ma non riesco a trovare informazioni complete su come usarlo. Al momento posso utilizzare solo le migrazioni un contesto alla volta.

Qualcuno può fornire un esempio con dettagli sufficienti per una nuova persona a EF come me da capire e utilizzare.

Risposte:


176

Entity Framework 6 ha aggiunto il supporto per più messaggi di posta DbContextelettronica aggiungendo i flag -ContextTypeNamee -MigrationsDirectory. Ho appena eseguito i comandi nella mia console di Gestione pacchetti e ho incollato l'output di seguito ...

Se hai 2 DbContexts nel tuo progetto e corri enable-migrations, riceverai un errore (come probabilmente già sai):

PM> enable-migrations
More than one context type was found in the assembly 'WebApplication3'.
To enable migrations for 'WebApplication3.Models.ApplicationDbContext', use Enable-Migrations -ContextTypeName WebApplication3.Models.ApplicationDbContext.
To enable migrations for 'WebApplication3.Models.AnotherDbContext', use Enable-Migrations -ContextTypeName WebApplication3.Models.AnotherDbContext.

Quindi devi eseguire enable-migrationsciascuno DbContextseparatamente. E devi specificare una cartella per ogni Configuration.csfile da generare ...

PM> Enable-Migrations -ContextTypeName ApplicationDbContext -MigrationsDirectory Migrations\ApplicationDbContext
Checking if the context targets an existing database...
Code First Migrations enabled for project WebApplication3.

PM> Enable-Migrations -ContextTypeName AnotherDbContext -MigrationsDirectory Migrations\AnotherDbContext
Checking if the context targets an existing database...
Code First Migrations enabled for project WebApplication3.

Per aggiungere migrazioni per ciascuna DbContext, lo fai in questo modo specificando il nome completo della Configurationclasse:

PM> Add-Migration -ConfigurationTypeName WebApplication3.Migrations.ApplicationDbContext.Configuration "InitialDatabaseCreation"
Scaffolding migration 'InitialDatabaseCreation'.
The Designer Code for this migration file includes a snapshot of your current Code First model. This snapshot is used to calculate the changes to your model when you scaffold the next migration. If you make additional changes to your model that you want to include in this migration, then you can re-scaffold it by running 'Add-Migration InitialDatabaseCreation' again.

PM> Add-Migration -ConfigurationTypeName WebApplication3.Migrations.AnotherDbContext.Configuration "InitialDatabaseCreation"
Scaffolding migration 'InitialDatabaseCreation'.
The Designer Code for this migration file includes a snapshot of your current Code First model. This snapshot is used to calculate the changes to your model when you scaffold the next migration. If you make additional changes to your model that you want to include in this migration, then you can re-scaffold it by running 'Add-Migration InitialDatabaseCreation' again.

E corri update-databaseallo stesso modo:

PM> Update-Database -ConfigurationTypeName WebApplication3.Migrations.ApplicationDbContext.Configuration
Specify the '-Verbose' flag to view the SQL statements being applied to the target database.
Applying explicit migrations: [201402032113124_InitialDatabaseCreation].
Applying explicit migration: 201402032113124_InitialDatabaseCreation.
Running Seed method.

PM> Update-Database -ConfigurationTypeName WebApplication3.Migrations.AnotherDbContext.Configuration
Specify the '-Verbose' flag to view the SQL statements being applied to the target database.
Applying explicit migrations: [201402032113383_InitialDatabaseCreation].
Applying explicit migration: 201402032113383_InitialDatabaseCreation.
Running Seed method.

Spero che questo ti aiuti.


Devo avere una stringa di connessione separata per ogni contesto o c'è un modo per aggirare questo?
Lrayh

3
Possono condividere la stessa stringa di connessione. Ma vuoi assicurarti che non siano mappati sulle stesse tabelle.
Anthony Chu

Se vengono mappati alla stessa tabella, puoi comunque definire quale migrazione verrà eseguita per prima e lasciare che il suo file di migrazione crei la tabella e quale verrà eseguita per secondo e modificarla in modo che non crei la tabella già esistente. È quindi possibile utilizzare la MigrateDatabaseToLatestVersionforzatura ctx.Database.initialize()di ogni contesto per eseguire nell'ordine corretto o eseguire il Update-Databasecomando manualmente nell'ordine corretto. (E viceversa, se esegui una migrazione del db alla versione precedente). È "pericoloso" ma può essere fatto.
JotaBe

Quindi avevo aggiunto le migrazioni al mio progetto e creato un contesto diverso da ApplicationDbContext. Ho continuato a utilizzare quel contesto che era i dati relativi al sito per circa 6 mesi, poi è arrivato il momento di iniziare a scherzare con il mio ApplicationUser. Il mio login e registrazione di base funzionava, ma volevo estendere la classe utente per aggiungere alcuni campi aggiuntivi. Questa risposta è stata molto utile per impostare una nuova configurazione di migrazione per quel contesto. Grazie! # 1up
Eric Bishard

1
se posso darti un +10 per questa risposta breve ma più che sufficiente lo farei, grazie @AnthonyChu.
Karim AG
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.