如何为多个上下文启用EF迁移来分离数据库?

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

 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. Migrations have already been enabled in project 'DatabaseService'. To overwrite the existing migrations configuration, use the -Force parameter.

第二次调用Enable-Migrations失败,因为Configuration.cs文件已经存在。 如果您重命名该类和文件,则应该能够运行第二个启用迁移,这将创build另一个Configuration.cs。

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

 Update-Database -ConfigurationTypeName MyRenamedConfiguration 

除了@ckalbuild议的内容之外,为每个重命名的Configuration.cs提供它自己的命名空间也是至关重要的 。 如果不这样做,EF将尝试将迁移应用到错误的上下文中。

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

如果迁移混乱,你想创build一个新的“基准”:

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

创build初始迁移:

  1. 在包pipe理器控制台中:

     Enable-Migrations -EnableAutomaticMigrations -ContextTypeName NamespaceOfContext.ContextA -ProjectName ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject -ConnectionStringName ContextA 
  2. 在解决scheme资源pipe理器中:将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. 在解决scheme资源pipe理器中:将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 

在包pipe理器控制台中创build迁移脚本的步骤:

  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 

我碰到同样的问题,我使用了以下解决scheme(全部来自软件包pipe理器控制台)

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

这将在Migrations文件夹中创build2个单独的文件夹。 每个将包含生成的Configuration.cs文件。 不幸的是,你仍然需要重命名这些Configuration.cs文件,否则会有投诉,其中有两个。 我将我的文件重命名为ConfigA.csConfigB.cs

编辑 :(礼貌凯文McPheat)记得重命名Configuration.cs文件时,也重命名类名称和构造/ EDIT

有了这个结构,你可以简单地做

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

这将在configuration文件旁边的文件夹内创build用于迁移的代码文件(将这些文件保存在一起很好)

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

最后但并非最不重要的是,这两个命令将正确的迁移应用到它们的数据库。

编辑08二月,2016:我已经做了一点与EF7版本7.0.0-rc1-16348testing

我无法获得-o | –outputDir选项的工作。 它继续给Microsoft.Dnx.Runtime.Common.Commandline.CommandParsingException: Unrecognized command or argument

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

原来的名字ContextA似乎违反了一些命名约定,所以我现在使用ContextAContextContextBContext 。 使用这些名字你可以使用下面的命令:(注意,我的dnx仍然可以在包pipe理器控制台上运行,我不想打开一个单独的CMD窗口来进行迁移)

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

这将在ContextAContextMigrations文件夹中创build模型快照和初始迁移。 它将创build一个名为ContextB的文件夹,其中包含ContextB的这些文件

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

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

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

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

如果你已经有一个“configuration”与许多迁移,并希望保持原样,你可以随时创build一个新的“configuration”类,给它另一个名字,像

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

那么只需发出命令

 Add-Migration -ConfigurationTypeName MyNewContextConfiguration InitialMigrationName 

而英孚将会毫不费力地支持移徙。 最后更新你的数据库,从现在开始,如果你不告诉他你想要更新哪个configuration,EF会报错:

 Update-Database -ConfigurationTypeName MyNewContextConfiguration 

完成。

您不需要处理启用迁移,因为它会抱怨“configuration”已经存在,重命名现有的configuration类将带来问题的迁移历史。

您可以定位不同的数据库,或者同一个数据库,所有的configuration将很好地共享__MigrationHistory表。