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

时间:2012-11-20 09:14:07

标签: .net entity-framework entity-framework-5 database-migration

如何在同一个项目中为多个数据库上下文启用Entity Framework 5(版本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.

6 个答案:

答案 0 :(得分:120)

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

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

Update-Database -ConfigurationTypeName MyRenamedConfiguration

答案 1 :(得分:95)

除了@ckal建议的内容之外,为每个重命名的Configuration.cs提供自己的命名空间是 critical 。如果不这样做,EF将尝试将迁移应用于错误的上下文。

以下是适合我的具体步骤。

如果迁移混乱并且您想要创建新的“基线”:

  1. 删除迁移文件夹中的所有现有.cs文件
  2. 在SSMS中,删除__MigrationHistory系统表。
  3. 创建初始迁移:

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

      Enable-Migrations -EnableAutomaticMigrations -ContextTypeName
      NamespaceOfContext.ContextA -ProjectName ProjectContextIsInIfNotMainOne
      -StartupProjectName NameOfMainProject  -ConnectionStringName ContextA
      
    2. 在Solution Explorer中:将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. 在Solution Explorer中:将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
      
    9. 在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
        

答案 2 :(得分:71)

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

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

这将在Migrations文件夹中创建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

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

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

我无法使-o | --outputDir选项起作用。它继续给予Microsoft.Dnx.Runtime.Common.Commandline.CommandParsingException: Unrecognized command or argument

然而,它似乎是第一次添加迁移时,它会被添加到Migrations文件夹中,而另一个上下文的后续迁移会自动放入迁移的子目录中。

原始名称ContextA似乎违反了某些命名惯例,因此我现在使用ContextAContextContextBContext。使用这些名称可以使用以下命令: (请注意,我的dnx仍然可以从包管理器控制台运行,我不想打开一个单独的CMD窗口来进行迁移)

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

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

的这些文件

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

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

.ContextA

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

答案 3 :(得分:7)

如果您已经拥有"配置"通过许多迁移并希望保持原样,您可以随时创建一个新的"配置" class,给它另一个名字,比如

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

然后发出命令

Add-Migration -ConfigurationTypeName MyNewContextConfiguration InitialMigrationName

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

Update-Database -ConfigurationTypeName MyNewContextConfiguration 

完成。

您不需要处理启用迁移,因为它会抱怨&#34;配置&#34;已经存在,重命名现有的配置类会给迁移历史记录带来问题。

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

答案 4 :(得分:0)

要在PowerShell中按照以下代码更新数据库类型...

Update-Database -context EnrollmentAppContext

*如果存在多个数据库,则仅使用此代码,否则没有必要。.

答案 5 :(得分: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.