Wiele kontekstów bazy danych w tej samej bazie danych i aplikacji w EF 6 i migracjach Code First

95

Jestem nowy w Entity Framework. Próbuję skonfigurować aplikację MVC, która używa EF 6. Używam migracji Code First. Używam obszarów w aplikacji i chciałbym mieć różne DbContexts w każdym obszarze, aby je rozbić. Wiem, że EF 6 ma ContextKey, ale nie mogę znaleźć pełnych informacji o tym, jak go używać. Obecnie mogę używać migracji tylko jednego kontekstu naraz.

Czy ktoś może podać przykład wystarczająco szczegółowy, aby nowa osoba, taka jak ja, zrozumiała i wykorzystała EF.

Lrayh
źródło

Odpowiedzi:

177

Entity Framework 6 dodał obsługę wielu DbContexts, dodając flagi -ContextTypeNamei -MigrationsDirectory. Właśnie uruchomiłem polecenia w mojej konsoli Menedżera pakietów i wkleiłem poniższe dane wyjściowe ...

Jeśli masz 2 DbContextsekundy w swoim projekcie i uruchomisz enable-migrations, pojawi się błąd (jak prawdopodobnie już wiesz):

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.

Musisz więc biegać enable-migrationspo każdym DbContextosobno. I musisz określić folder dla każdego Configuration.cspliku, który ma zostać wygenerowany ...

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.

Aby dodać migracje dla każdego DbContext, robisz to w ten sposób, określając w pełni kwalifikowaną nazwę Configurationklasy:

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.

I biegasz w update-databaseten sam sposób:

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.

Mam nadzieję że to pomoże.

Anthony Chu
źródło
Czy muszę mieć oddzielne parametry połączenia dla każdego kontekstu, czy jest na to sposób?
Lrayh
3
Mogą udostępniać te same parametry połączenia. Ale chcesz się upewnić, że nie są mapowane na te same tabele.
Anthony Chu
Jeśli mapują na tę samą tabelę, nadal można zdefiniować, która migracja zostanie uruchomiona jako pierwsza i pozostawić jej plik migracji, aby utworzyć tabelę, a która uruchomi się jako druga, i zmodyfikować ją tak, aby nie tworzyła już istniejącej tabeli. Następnie możesz użyć MigrateDatabaseToLatestVersionforzing the ctx.Database.initialize()każdego kontekstu, aby uruchomić we właściwej kolejności, lub uruchomić Update-Databasepolecenie ręcznie we właściwej kolejności. (I odwrotnie, jeśli wykonasz migrację bazy danych do poprzedniej wersji). Jest to „niebezpieczne”, ale można to zrobić.
JotaBe
Dlatego dodałem migracje do mojego projektu i utworzyłem kontekst inny niż ApplicationDbContext. Zacząłem używać tego kontekstu, który był danymi dotyczącymi witryny przez około 6 miesięcy, a potem przyszedł czas, aby zacząć bawić się z moim ApplicationUser. Moje podstawowe logowanie i rejestracja działały, ale chciałem rozszerzyć klasę użytkowników o dodatkowe pola. Ta odpowiedź była bardzo pomocna przy tworzeniu nowej konfiguracji migracji dla tego kontekstu. Dziękuję Ci! # 1up
Eric Bishard
1
jeśli mogę dać ci +10 za tę krótką, ale więcej niż wystarczającą odpowiedź, dziękuję @AnthonyChu.
Karim AG