问题
How do I enable Entity Framework 5 (version 5.0.0) migrations for multiple DB contexts in the same project, where each context corresponds to its own database? When I run Enable-Migrations
in the PM console (Visual Studio 2012), there's an error because of there being multiple contexts:
PM> Enable-Migrations
More than one context type was found in the assembly 'DatabaseService'.
To enable migrations for DatabaseService.Models.Product1DbContext, use Enable-Migrations -ContextTypeName DatabaseService.Models.Product1DbContext.
To enable migrations for DatabaseService.Models.Product2DbContext, use Enable-Migrations -ContextTypeName DatabaseService.Models.Product2DbContext.
If I run Enable-Migrations -ContextTypeName DatabaseService.Models.Product1DbContext
I'm not allowed to run Enable-Migrations -ContextTypeName DatabaseService.Models.Product2DbContext
because a migration already exists: Migrations have already been enabled in project 'DatabaseService'. To overwrite the existing migrations configuration, use the -Force parameter.
回答1:
The 2nd call to Enable-Migrations is failing because the Configuration.cs file already exists. If you rename that class and file, you should be able to run that 2nd Enable-Migrations, which will create another Configuration.cs.
You will then need to specify which configuration you want to use when updating the databases.
Update-Database -ConfigurationTypeName MyRenamedConfiguration
回答2:
In addition to what @ckal suggested, it is critical to give each renamed Configuration.cs its own namespace. If you do not, EF will attempt to apply migrations to the wrong context.
Here are the specific steps that work well for me.
If Migrations are messed up and you want to create a new "baseline":
- Delete any existing .cs files in the Migrations folder
- In SSMS, delete the __MigrationHistory system table.
Creating the initial migration:
In Package Manager Console:
Enable-Migrations -EnableAutomaticMigrations -ContextTypeName NamespaceOfContext.ContextA -ProjectName ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject -ConnectionStringName ContextA
In Solution Explorer: Rename Migrations.Configuration.cs to Migrations.ConfigurationA.cs. This should automatically rename the constructor if using Visual Studio. Make sure it does. Edit ConfigurationA.cs: Change the namespace to NamespaceOfContext.Migrations.MigrationsA
Enable-Migrations -EnableAutomaticMigrations -ContextTypeName NamespaceOfContext.ContextB -ProjectName ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject -ConnectionStringName ContextB
In Solution Explorer: Rename Migrations.Configuration.cs to Migrations.ConfigurationB.cs. Again, make sure the constructor is also renamed appropriately. Edit ConfigurationB.cs: Change the namespace to NamespaceOfContext.Migrations.MigrationsB
add-migration InitialBSchema -IgnoreChanges -ConfigurationTypeName ConfigurationB -ProjectName ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject -ConnectionStringName ContextB
Update-Database -ConfigurationTypeName ConfigurationB -ProjectName ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject -ConnectionStringName ContextB
add-migration InitialSurveySchema -IgnoreChanges -ConfigurationTypeName ConfigurationA -ProjectName ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject -ConnectionStringName ContextA
Update-Database -ConfigurationTypeName ConfigurationA -ProjectName ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject -ConnectionStringName ContextA
Steps to create migration scripts in Package Manager Console:
Run command
Add-Migration MYMIGRATION -ConfigurationTypeName ConfigurationA -ProjectName ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject -ConnectionStringName ContextA
or -
Add-Migration MYMIGRATION -ConfigurationTypeName ConfigurationB -ProjectName ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject -ConnectionStringName ContextB
It is OK to re-run this command until changes are applied to the DB.
Either run the scripts against the desired local database, or run Update-Database without -Script to apply locally:
Update-Database -ConfigurationTypeName ConfigurationA -ProjectName ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject -ConnectionStringName ContextA
or -
Update-Database -ConfigurationTypeName ConfigurationB -ProjectName ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject -ConnectionStringName ContextB
回答3:
I just bumped into the same problem and I used the following solution (all from Package Manager Console)
PM> Enable-Migrations -MigrationsDirectory "Migrations\ContextA" -ContextTypeName MyProject.Models.ContextA
PM> Enable-Migrations -MigrationsDirectory "Migrations\ContextB" -ContextTypeName MyProject.Models.ContextB
This will create 2 separate folders in the Migrations folder. Each will contain the generated Configuration.cs
file. Unfortunately you still have to rename those Configuration.cs
files otherwise there will be complaints about having two of them. I renamed my files to ConfigA.cs
and ConfigB.cs
EDIT: (courtesy Kevin McPheat) Remember when renaming the Configuration.cs files, also rename the class names and constructors /EDIT
With this structure you can simply do
PM> Add-Migration -ConfigurationTypeName ConfigA
PM> Add-Migration -ConfigurationTypeName ConfigB
Which will create the code files for the migration inside the folder next to the config files (this is nice to keep those files together)
PM> Update-Database -ConfigurationTypeName ConfigA
PM> Update-Database -ConfigurationTypeName ConfigB
And last but not least those two commands will apply the correct migrations to their corrseponding databases.
EDIT 08 Feb, 2016: I have done a little testing with EF7 version 7.0.0-rc1-16348
I could not get the -o|--outputDir option to work. It kept on giving Microsoft.Dnx.Runtime.Common.Commandline.CommandParsingException: Unrecognized command or argument
However it looks like the first time an migration is added it is added into the Migrations folder, and a subsequent migration for another context is automatically put into a subdolder of migrations.
The original names ContextA
seems to violate some naming conventions so I now use ContextAContext
and ContextBContext
. Using these names you could use the following commands:
(note that my dnx still works from the package manager console and I do not like to open a separate CMD window to do migrations)
PM> dnx ef migrations add Initial -c "ContextAContext"
PM> dnx ef migrations add Initial -c "ContextBContext"
This will create a model snapshot and a initial migration in the Migrations
folder for ContextAContext
. It will create a folder named ContextB
containing these files for ContextBContext
I manually added a ContextA
folder and moved the migration files from ContextAContext
into that folder. Then I renamed the namespace inside those files (snapshot file, initial migration and note that there is a third file under the initial migration file ... designer.cs). I had to add .ContextA
to the namespace, and from there the framework handles it automatically again.
Using the following commands would create a new migration for each context
PM> dnx ef migrations add Update1 -c "ContextAContext"
PM> dnx ef migrations add Update1 -c "ContextBContext"
and the generated files are put in the correct folders.
回答4:
In case you already have a "Configuration" with many migrations and want to keep this as is, you can always create a new "Configuration" class, give it another name, like
class MyNewContextConfiguration : DbMigrationsConfiguration<MyNewDbContext>
{
...
}
then just issue the command
Add-Migration -ConfigurationTypeName MyNewContextConfiguration InitialMigrationName
and EF will scaffold the migration without problems. Finally update your database, from now on, EF will complain if you don't tell him which configuration you want to update:
Update-Database -ConfigurationTypeName MyNewContextConfiguration
Done.
You don't need to deal with Enable-Migrations as it will complain "Configuration" already exists, and renaming your existing Configuration class will bring issues to the migration history.
You can target different databases, or the same one, all configurations will share the __MigrationHistory table nicely.
回答5:
To update database type following codes in PowerShell...
Update-Database -context EnrollmentAppContext
*if more than one databases exist only use this codes,otherwise not necessary..
回答6:
If more databases exist use following codes in PowerShell
Add-Migration Starter -context EnrollmentAppContext
'Starter' is Migration Name
'EnrollmentAppContext' is name of my app Context
You can open PowerShell in VS by doing:
Tools->NuGet Package Manager->Package Manager Console
回答7:
EF 4.7 actually gives a hint when you run Enable-migrations at multiple context.
More than one context type was found in the assembly 'Service.Domain'.
To enable migrations for 'Service.Domain.DatabaseContext.Context1',
use Enable-Migrations -ContextTypeName Service.Domain.DatabaseContext.Context1.
To enable migrations for 'Service.Domain.DatabaseContext.Context2',
use Enable-Migrations -ContextTypeName Service.Domain.DatabaseContext.Context2.
来源:https://stackoverflow.com/questions/13469881/how-do-i-enable-ef-migrations-for-multiple-contexts-to-separate-databases