如何为多个上下文启用EF迁移到单独的数据库?


122

如何为同一项目中的多个数据库上下文启用Entity Framework 5(版本5.0.0)迁移,其中每个上下文都对应于其自己的数据库?当我Enable-Migrations在PM控制台(Visual Studio 2012)中运行时,出现错误,因为存在多个上下文:

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.

如果我运行,则Enable-Migrations -ContextTypeName DatabaseService.Models.Product1DbContext不允许运行,Enable-Migrations -ContextTypeName DatabaseService.Models.Product2DbContext因为迁移已存在:Migrations have already been enabled in project 'DatabaseService'. To overwrite the existing migrations configuration, use the -Force parameter.


Answers:


126

由于Configuration.cs文件已经存在,因此对Enable-Migrations的第二次调用失败。如果重命名该类和文件,则应该能够运行该第二个Enable-Migrations,这将创建另一个Configuration.cs。

然后,您将需要指定在更新数据库时要使用的配置。

Update-Database -ConfigurationTypeName MyRenamedConfiguration

1
什么是“ MyRenamedConfiguration”?
罗伯特·诺亚克

1
作为示例,“ MyRenamedConfiguration”只是占位符文本。您可以将原始Configuration.cs重命名为任何名称(例如FooBar,然后运行Update-Database -ConfigurationTypeName FooBar)。
ckal 2014年

3
缩写形式:Update-Database -conf MyRenamedConfiguration
Peter Kerr

100

除了@ckal建议什么,这是至关重要的给每个重命名Configuration.cs自己的命名空间。如果您不这样做,EF将尝试将迁移应用于错误的上下文。

以下是适合我的特定步骤。

如果迁移搞砸了,而您想创建一个新的“基准”:

  1. 删除Migrations文件夹中的所有现有.cs文件
  2. 在SSMS中,删除__MigrationHistory系统表。

创建初始迁移:

  1. 在软件包管理器控制台中:

    Enable-Migrations -EnableAutomaticMigrations -ContextTypeName
    NamespaceOfContext.ContextA -ProjectName ProjectContextIsInIfNotMainOne
    -StartupProjectName NameOfMainProject  -ConnectionStringName ContextA
  2. 在解决方案资源管理器中:将Migrations.Configuration.cs重命名为Migrations.ConfigurationA.cs。如果使用Visual Studio,这应该自动重命名构造函数。确保确实如此。编辑ConfigurationA.cs:将名称空间更改为NamespaceOfContext.Migrations.MigrationsA

  3. Enable-Migrations -EnableAutomaticMigrations -ContextTypeName
    NamespaceOfContext.ContextB -ProjectName ProjectContextIsInIfNotMainOne
    -StartupProjectName NameOfMainProject  -ConnectionStringName ContextB
  4. 在解决方案资源管理器中:将Migrations.Configuration.cs重命名为Migrations.ConfigurationB.cs。再次,确保构造函数也已正确重命名。编辑ConfigurationB.cs:将名称空间更改为NamespaceOfContext.Migrations.MigrationsB

  5. add-migration InitialBSchema -IgnoreChanges -ConfigurationTypeName
    ConfigurationB -ProjectName ProjectContextIsInIfNotMainOne
    -StartupProjectName NameOfMainProject  -ConnectionStringName ContextB 
  6. Update-Database -ConfigurationTypeName ConfigurationB -ProjectName
    ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
    -ConnectionStringName ContextB
  7. add-migration InitialSurveySchema -IgnoreChanges -ConfigurationTypeName
    ConfigurationA -ProjectName ProjectContextIsInIfNotMainOne -StartupProjectName
    NameOfMainProject  -ConnectionStringName ContextA 
  8. Update-Database -ConfigurationTypeName ConfigurationA -ProjectName
    ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
    -ConnectionStringName ContextA

在Package Manager控制台中创建迁移脚本的步骤:

  1. 运行命令

    Add-Migration MYMIGRATION -ConfigurationTypeName ConfigurationA -ProjectName
    ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
    -ConnectionStringName ContextA

    要么 -

    Add-Migration MYMIGRATION -ConfigurationTypeName ConfigurationB -ProjectName
    ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
    -ConnectionStringName ContextB

    可以重新运行此命令,直到对数据库应用更改为止。

  2. 针对所需的本地数据库运行脚本,或者运行不带-Script的Update-Database以在本地应用:

    Update-Database -ConfigurationTypeName ConfigurationA -ProjectName
    ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
    -ConnectionStringName ContextA

    要么 -

    Update-Database -ConfigurationTypeName ConfigurationB -ProjectName
    ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
    -ConnectionStringName ContextB

#4更改:编辑ConfigurationA.cs->编辑ConfigurationB.cs
Brian Rizo 2014年

1
@Biran:感谢您注意到这一点。我编辑了答案。注意,您也可以自己编辑答案。由于您还没有2000年的声誉,因此您的回答会进入审核队列,但是通常可以快速完成,因此您的编辑可能会在几分钟之内获得批准。
Eric J.

5
谢谢!那就是我所缺少的(名称空间)。
William M. Rawls

这可能会有所帮助,因为最初我不清楚如何在步骤2和步骤4中进行重命名:将Configuration.cs文件重命名为ConfigurationA.cs或ConfigurationB.cs时,重命名还应导致类和其构造函数也被重命名为ConfigurationA或ConfigurationB。无法重命名该类将在您运行add-migration命令时导致错误消息- “在程序集'...'中找不到迁移配置类型'ConfigurationA'” –是的,措辞很糟糕,就像我在VS2013中收到的错误消息中的内容-大声笑
Greg Barth

3
这帮助了我!有关所有选项和订单的完整说明。节省了我几个小时
elcool

81

我碰到了同样的问题,并且使用了以下解决方案(均来自Package Manager Console)

PM> Enable-Migrations -MigrationsDirectory "Migrations\ContextA" -ContextTypeName MyProject.Models.ContextA
PM> Enable-Migrations -MigrationsDirectory "Migrations\ContextB" -ContextTypeName MyProject.Models.ContextB

这将在“迁移”文件夹中创建2个单独的文件夹。每个将包含生成的Configuration.cs文件。不幸的是,您仍然必须重命名这些Configuration.cs文件,否则会有两个文件的抱怨。我将文件重命名为ConfigA.csConfigB.cs

编辑:(由Kevin McPheat提供)记住重命名Configuration.cs文件时,还要重命名类名和构造函数/ EDIT

有了这种结构,您只需

PM> Add-Migration -ConfigurationTypeName ConfigA
PM> Add-Migration -ConfigurationTypeName ConfigB

它将在配置文件旁边的文件夹内创建用于迁移的代码文件(将这些文件保存在一起很不错)

PM> Update-Database -ConfigurationTypeName ConfigA
PM> Update-Database -ConfigurationTypeName ConfigB

最后但并非最不重要的一点是,这两个命令会将正确的迁移应用于其相应的数据库。

编辑2016年2月8日: 我对EF7版本7.0.0-rc1-16348做了一些测试

我无法使用-o | --outputDir选项。它一直在给Microsoft.Dnx.Runtime.Common.Commandline.CommandParsingException: Unrecognized command or argument

但是,看起来好像是第一次添加迁移时,它将添加到“迁移”文件夹中,并且针对其他上下文的后续迁移会自动放入迁移的子子目录中。

原始名称ContextA似乎违反了某些命名约定,因此我现在使用ContextAContextContextBContext。使用这些名称,您可以使用以下命令:(请注意,我的dnx仍然可以在程序包管理器控制台中运行,并且我不喜欢打开单独的CMD窗口进行迁移)

PM> dnx ef migrations add Initial -c "ContextAContext"
PM> dnx ef migrations add Initial -c "ContextBContext"

这将在的Migrations文件夹中创建模型快照和初始迁移ContextAContext。它将创建一个名为ContextB的文件夹,其中包含以下文件ContextBContext

我手动添加了一个ContextA文件夹,并将迁移文件从ContextAContext该文件夹移到了该文件夹中。然后,我在这些文件(快照文件,初始迁移文件,并注意在初始迁移文件... designer.cs下还有第三个文件)中重命名了命名空间。我必须添加.ContextA到名称空间,然后框架从那里再次自动处理它。

使用以下命令将为每个上下文创建一个新的迁移

PM>  dnx ef migrations add Update1 -c "ContextAContext"
PM>  dnx ef migrations add Update1 -c "ContextBContext"

并将生成的文件放在正确的文件夹中。


5
最好的解决方案,简单,我们保留一个清晰的文件夹。
马里克

2
这就是我需要的答案。通过-MigrationsDirectory添加的名称空间就是答案!谢谢。
crob

1
干净的解决方案。谢谢。
Stefan Cebulak

4
1.5年后,我很高兴可以使用自己的帖子来设置一个新项目。
bart s

1
请注意,在您运行时,add-migration它会提示您输入Name。因为我已经提供了ConfigurationTypeName,这使我有点不高兴,刚说的时候有点生气Name:。但是,当然,它想要的名称是该更改的“易于阅读的”描述-例如。AddedProductsIncreaseLengthOfNameFields。在Migrations文件夹中,您将获得此名称作为类名的一部分,因此很容易看到是什么。所以实际上Name有点像签到评论。
Simon_Weaver

7

如果您已经有一个“配置”并进行了许多迁移,并且希望保持原样,则可以随时创建一个新的“配置”类,并为其命名,例如

class MyNewContextConfiguration : DbMigrationsConfiguration<MyNewDbContext>
{
   ...
}

然后发出命令

Add-Migration -ConfigurationTypeName MyNewContextConfiguration InitialMigrationName

EF会毫不费力地支持迁移。最后更新您的数据库,从现在开始,如果您不告诉他您想更新哪个配置,EF将会抱怨:

Update-Database -ConfigurationTypeName MyNewContextConfiguration 

做完了

您无需处理Enable-Migrations,因为它会抱怨“ Configuration”已经存在,而重命名现有Configuration类将给迁移历史带来问题。

您可以针对不同的数据库,也可以针对同一数据库,所有配置将很好地共享__MigrationHistory表。


4

如果存在更多数据库,请在PowerShell中使用以下代码

Add-Migration Starter -context EnrollmentAppContext 
  • “启动器”是迁移名称

  • “ EnrollmentAppContext”是我的应用上下文的名称

您可以通过执行以下操作在VS中打开PowerShell: Tools->NuGet Package Manager->Package Manager Console


1
这对我有帮助。谢谢!:)
noobprogrammer


0

当您在多个上下文中运行Enable-migrations时,EF 4.7实际上会给出提示。

在程序集“ 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.
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.