Multiple DB Contexts in the Same DB and Application in EF 6 and Code First Migrations
Asked Answered
L

1

97

I'm new to Entity Framework. I am trying to setup an MVC Application what uses EF 6. I am using Code First Migrations. I am using Areas in the app and would like to have different DbContexts in each area to break it up. I know EF 6 has ContextKey, but I can't find complete information on how to use it. Currently I can only use migrations one context at a time.

Can someone give an example with enough detail for a new person to EF like me to understand and use.

Loveliesbleeding answered 3/2, 2014 at 20:55 Comment(0)
H
178

Entity Framework 6 added support for multiple DbContexts by adding the -ContextTypeName and -MigrationsDirectory flags. I just ran the commands in my Package Manager Console and pasted the output below...

If you have 2 DbContexts in your project and you run enable-migrations, you'll get an error (as you probably already know):

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.

So you have to run enable-migrations on each DbContext separately. And you have to specify a folder for each Configuration.cs file to be generated...

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.

To add migrations for each DbContext, you do it like this by specifying the fully qualified name of the Configuration class:

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.

And you run update-database the same way:

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.
Hurdle answered 3/2, 2014 at 21:25 Comment(6)
Do I have to have a separate connection string for each context or is there a way around that?Loveliesbleeding
They can share the same connection string. But you want to make sure they don't map to the same tables.Hurdle
If they do map to the same table, you can still define which migration will run first, and leave its migration file create the table, and which will run second, and modify it so that it doesn't create the already exiting table. You can then use MigrateDatabaseToLatestVersion forzing the ctx.Database.initialize() of each context to run in the correct order, or run the Update-Database command by hand in the correct order. (And teh reverse, if you do a db migration to previous version). It`s "dangerous" but can be done.Tibbs
So I had added migrations to my project and created a context different than ApplicationDbContext. I went on to use that context which was site related data for about 6 months, then it came time to start messing around with my ApplicationUser. My basic login and registration was working, but I wanted to extend the user class to add some additional fields. This answer was very helpful in setting up a new migration configuration for that context. Thank you! #1upHypostasis
if I can give you a +10 for this short but more than enough answer I would, Thanks @AnthonyChu.Turpeth
This is the perfect answer, and ended many hours of debugging frustration for me. Thank you so much!Striate

© 2022 - 2024 — McMap. All rights reserved.