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

akn*_*ds1 118 .net entity-framework database-migration entity-framework-5

如何在同一项目中为多个数据库上下文启用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.
Run Code Online (Sandbox Code Playgroud)

如果我运行,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.

cka*_*kal 123

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

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

Update-Database -ConfigurationTypeName MyRenamedConfiguration
Run Code Online (Sandbox Code Playgroud)

  • 缩短形式:Update-Database -conf MyRenamedConfiguration (4认同)

Eri*_* J. 96

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

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

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

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

创建初始迁移:

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

    Enable-Migrations -EnableAutomaticMigrations -ContextTypeName
    NamespaceOfContext.ContextA -ProjectName ProjectContextIsInIfNotMainOne
    -StartupProjectName NameOfMainProject  -ConnectionStringName ContextA
    
    Run Code Online (Sandbox Code Playgroud)
  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
    
    Run Code Online (Sandbox Code Playgroud)
  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 
    
    Run Code Online (Sandbox Code Playgroud)
  6. Update-Database -ConfigurationTypeName ConfigurationB -ProjectName
    ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
    -ConnectionStringName ContextB
    
    Run Code Online (Sandbox Code Playgroud)
  7. add-migration InitialSurveySchema -IgnoreChanges -ConfigurationTypeName
    ConfigurationA -ProjectName ProjectContextIsInIfNotMainOne -StartupProjectName
    NameOfMainProject  -ConnectionStringName ContextA 
    
    Run Code Online (Sandbox Code Playgroud)
  8. Update-Database -ConfigurationTypeName ConfigurationA -ProjectName
    ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
    -ConnectionStringName ContextA
    
    Run Code Online (Sandbox Code Playgroud)

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

  1. 运行命令

    Add-Migration MYMIGRATION -ConfigurationTypeName ConfigurationA -ProjectName
    ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
    -ConnectionStringName ContextA
    
    Run Code Online (Sandbox Code Playgroud)

    要么 -

    Add-Migration MYMIGRATION -ConfigurationTypeName ConfigurationB -ProjectName
    ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
    -ConnectionStringName ContextB
    
    Run Code Online (Sandbox Code Playgroud)

    可以重新运行此命令,直到对DB应用更改为止.

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

    Update-Database -ConfigurationTypeName ConfigurationA -ProjectName
    ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
    -ConnectionStringName ContextA
    
    Run Code Online (Sandbox Code Playgroud)

    要么 -

    Update-Database -ConfigurationTypeName ConfigurationB -ProjectName
    ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
    -ConnectionStringName ContextB
    
    Run Code Online (Sandbox Code Playgroud)

  • 谢谢!这就是我所缺少的(命名空间). (4认同)
  • 这帮助了我!有关所有选项和订单的完整说明。节省了我几个小时 (3认同)

bar*_*t s 75

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

PM> Enable-Migrations -MigrationsDirectory "Migrations\ContextA" -ContextTypeName MyProject.Models.ContextA
PM> Enable-Migrations -MigrationsDirectory "Migrations\ContextB" -ContextTypeName MyProject.Models.ContextB
Run Code Online (Sandbox Code Playgroud)

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

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

有了这种结构,你可以做到

PM> Add-Migration -ConfigurationTypeName ConfigA
PM> Add-Migration -ConfigurationTypeName ConfigB
Run Code Online (Sandbox Code Playgroud)

这将为配置文件旁边的文件夹内的迁移创建代码文件(将这些文件保存在一起很好)

PM> Update-Database -ConfigurationTypeName ConfigA
PM> Update-Database -ConfigurationTypeName ConfigB
Run Code Online (Sandbox Code Playgroud)

最后但并非最不重要的是,这两个命令将正确的迁移应用于其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"
Run Code Online (Sandbox Code Playgroud)

这将在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"
Run Code Online (Sandbox Code Playgroud)

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

  • 最好的解决方案,简单,我们保持一个清晰的文件夹. (5认同)
  • 1.5年后,我很高兴我可以使用自己的帖子来设置一个新项目. (4认同)
  • 这就是我需要的答案.通过-MigrationsDirectory添加的命名空间就是答案!谢谢. (2认同)

Gui*_*ino 7

如果你已经有了一个"配置"与许多迁移,并希望保持这种作为是,你总是可以创建一个新的"配置"类,给它一个名称,如

class MyNewContextConfiguration : DbMigrationsConfiguration<MyNewDbContext>
{
   ...
}
Run Code Online (Sandbox Code Playgroud)

然后发出命令

Add-Migration -ConfigurationTypeName MyNewContextConfiguration InitialMigrationName
Run Code Online (Sandbox Code Playgroud)

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

Update-Database -ConfigurationTypeName MyNewContextConfiguration 
Run Code Online (Sandbox Code Playgroud)

完成.

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

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


AHA*_*QIB 6

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

Add-Migration Starter -context EnrollmentAppContext 
Run Code Online (Sandbox Code Playgroud)
  • “Starter”是迁移名称

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

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


AHA*_*QIB 5

要更新数据库,请在 PowerShell 中输入以下代码...

Update-Database -context EnrollmentAppContext
Run Code Online (Sandbox Code Playgroud)

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