Enity Framework 6.0.0.0:无法通过基于代码的迁移生成显式迁移 [英] Enity Framework 6.0.0.0 : Unable to generate an explicit migration... with Code-based migration
问题描述
情况是:
- 每租户数据库。
- 非自动基于代码基于迁移。 dbs的初始创建也是通过Code First。目前情况下没有预先存在的dbs。
- 在生成迁移脚本期间,确切的数据库不知道,因为有很多。我唯一需要的是代码 - 初始迁移脚本基于初始模型和模型进行了一些修改。
- 使用初始脚本生成的现有dbs - 一切正常。以下是我如何重现问题:
- 运行PS命令:添加迁移-Name初始--StartUpProjectName MyApp.Web -ProjectName MyApp.Migrations -ConfigurationTypeNameMyApp.Migrations.MyMigrationConfiguration-ConnectionString Data Source = .\SQLEXPRESS; Database = demo-db; Trusted_Connection = False; User ID = x; Password = x-ConnectionProviderNameSystem.Data.SqlClient - 工作正常
- 运行应用程序并创建数据库。停止应用程序修改模型。
- 运行PS命令:添加迁移-Name MySecondMigration -StartUpProjectName MyApp.Web -ProjectName MyApp.Migrations -ConfigurationTypeNameMyApp.Migrations.MyMigrationConfiguration-ConnectionString数据Source = .\SQLEXPRESS; Database = demo-db; Trusted_Connection = False; User ID = x; Password = x-ConnectionProviderNameSystem.Data.SqlClient - Boom。
- - 迁移者甚至不连接到MSSQL来检查数据库是否存在或具有dbo .__MigrationHistory!我已经进一步关闭了MSSQL服务! - 如果输入虚拟数据库名称或关闭整个MSSQL服务器无关紧要 - 错误是相同的,没有连接。那么当它不检查数据库时,它如何知道迁移正在等待?我假设一个bug。
- 我已经创建了__dbo.MigrationHistory,其中已初始化迁移。
- 错误:无法生成显式迁移,因为以下显式迁移待处理:[201402121953301_Initial]。在尝试生成新的显式迁移之前应用挂起的显式迁移。
- Per tenant db.
- Non-automatic Code-based based migration. The initial creation of the dbs is through Code First too. There are no preexisting dbs in the current scenario.
- The exact db is not known during the generation of migration script becase there are many. The only thing I have is code - the Initial migration script based on the model in the beginning and the model with some modifications.
- Existing dbs generated with initial script - everything works fine. Here is how I reproduce the problem :
- Run PS command : Add-Migration -Name Initial -StartUpProjectName MyApp.Web -ProjectName MyApp.Migrations -ConfigurationTypeName "MyApp.Migrations.MyMigrationConfiguration" -ConnectionString "Data Source=.\SQLEXPRESS;Database=demo-db;Trusted_Connection=False;User ID=x;Password=x" -ConnectionProviderName "System.Data.SqlClient" - Works Fine
- Run the app and the db is created. Stop the app. Make modification to the model.
- Run PS command : Add-Migration -Name MySecondMigration -StartUpProjectName MyApp.Web -ProjectName MyApp.Migrations -ConfigurationTypeName "MyApp.Migrations.MyMigrationConfiguration" -ConnectionString "Data Source=.\SQLEXPRESS;Database=demo-db;Trusted_Connection=False;User ID=x;Password=x" -ConnectionProviderName "System.Data.SqlClient" - Boom.
- Subtlety - The migrator does not even connect to MSSQL to check if the db even exists or has dbo.__MigrationHistory! I have goen further and turned off the MSSQL service! - It does not matter if I enter false db name or not or I turn off the entire MSSQL server - the error is the same and no connection is made. So how does it know a migration is pending when it does not check the database? I assume a bug.
- I have __dbo.MigrationHistory created already with the Initial migration in it.
- Error : Unable to generate an explicit migration because the following explicit migrations are pending: [201402121953301_Initial]. Apply the pending explicit migrations before attempting to generate a new explicit migration.
这是我的配置 - 没有什么特别的:
Here is my Configuration - nothing special :
public class MyMigrationConfiguration : DbMigrationsConfiguration<MyMigrationContext>
{
public MyMigrationConfiguration()
{
AutomaticMigrationsEnabled = false;
AutomaticMigrationDataLossAllowed = false;
MigrationsNamespace = "---";
MigrationsDirectory = "---";
}
}
这是我创建dbs的方法:
Here is the method with wich I create the dbs :
public void CreateOrUpdateDb(string DbName)
{
try
{
string connectionString = _connectionStringProvider.GetConnectionString(DbName);
DbMigrationsConfiguration cfg = CreateMigrationsConfig(connectionString);
cfg.AutomaticMigrationsEnabled = false;
cfg.AutomaticMigrationDataLossAllowed = false;
DbMigrator dbMigrator = new DbMigrator(cfg);
dbMigrator.Update();
}
catch (MigrationsException exception)
{
_logger.Error(string.Format("Error creating database '{0}'",DbName), exception);
}
}
我已经搜索并阅读了所有可以找到的内容网络,但大多数示例包括标准的Configuration.cs等。没有人解释为什么我应该运行Enable-Migrations,因为它创建了Configuration.cs,但是我自己提供了Configuration类,并且不需要这个其他类。
I have already searched and read whatever I can find on the web but most examples include the standart Configuration.cs and the like. Nobody explains why should I run Enable-Migrations because it creates Configuration.cs but I provide the Configuration class myself and do not need this other class.
这里是异常堆栈:
> System.Data.Entity.Migrations.Infrastructure.MigrationsPendingException: Unable to generate an explicit migration because the following explicit migrations are pending: [201402121953301_Initial]. Apply the pending explicit migrations before attempting to generate a new explicit migration.
at System.Data.Entity.Migrations.DbMigrator.Scaffold(String migrationName, String namespace, Boolean ignoreChanges)
at System.Data.Entity.Migrations.Design.MigrationScaffolder.Scaffold(String migrationName, Boolean ignoreChanges)
at System.Data.Entity.Migrations.Design.ToolingFacade.ScaffoldRunner.Scaffold(MigrationScaffolder scaffolder)
at System.Data.Entity.Migrations.Design.ToolingFacade.ScaffoldRunner.Run()
at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
at System.Data.Entity.Migrations.Design.ToolingFacade.Run(BaseRunner runner)
at System.Data.Entity.Migrations.Design.ToolingFacade.Scaffold(String migrationName, String language, String rootNamespace, Boolean ignoreChanges)
at System.Data.Entity.Migrations.AddMigrationCommand.Execute(String name, Boolean force, Boolean ignoreChanges)
at System.Data.Entity.Migrations.AddMigrationCommand.<>c__DisplayClass2.<.ctor>b__0()
有没有方式强制迁移者制作脚本,而不告诉我有一些挂起的迁移,即使没有?这是EF中的100%错误,但我不知道如何解决。
Is there any way to force the migrator to make the script without telling me that there are some pending migrations even though there are not? This is 100% bug in EF but I do not know how to get around it.
推荐答案
我们已经找到答案我的聪明的同事,并在反射器。的帮助下。
We have found the answer - a smart colleague of mine and with the help of Reflector.
- 在EntityFramework.dll里面有一个类
- System.Data.Entity.Migrations.DbMigrator用一个方法
- 脚手架(string migrationName,string @namespace,bool ignoreChanges)
- 哪个拨打这个.GetPendingMigrations
- 哪个方法在另一个类上调用另一个方法 HistoryRepository.CreateHistoryQuery (HistoryContext context,string contextKey = null),参数contextKey == NULL
-
但是这种方法里面有这样的情况
- Inside EntityFramework.dll there is the class
- System.Data.Entity.Migrations.DbMigrator with a method
- Scaffold(string migrationName, string @namespace, bool ignoreChanges)
- Which makes a call this.GetPendingMigrations
- Which method calls another method on another class HistoryRepository.CreateHistoryQuery(HistoryContext context, string contextKey = null) with the parameter contextKey == NULL
But there inside this method this happens
contex tKey =!string.IsNullOrWhiteSpace(contextKey)? contextKey.RestrictTo(this._contextKeyMaxLength):this._contextKey;
contextKey = !string.IsNullOrWhiteSpace(contextKey) ? contextKey.RestrictTo(this._contextKeyMaxLength) : this._contextKey;
,contextKey不再为空。 IT实际上成为类型(YourInheritedDbMigrationConfiguration).ToString()
and the contextKey is not null anymore. IT actually becomes the type(YourInheritedDbMigrationConfiguration).ToString()
问题在哪里?问题出在于
Where is the problem? The problem lies in the fact that
- 我使用两个不同的DbMigrationConfiguration类
- ,因为迁移程序集与应用程序的核心分开,使得
- 它们有两种不同的完全限定命名类,最终
- 导致两个不同的ContextKey在用于生成迁移脚本的DbMigrationConfiguration的dbo._MigrationHistory表中。
- I use two different DbMigrationConfiguration classes
- because the migration assembly is separated from the core of the application which makes
- them two differently 'fully qualified named classes' which at the end
- result in two different ContextKeys in the dbo._MigrationHistory table for the DbMigrationConfiguration which is used for the generation of the migration script.
所以当我进行初始迁移脚本并启动站点,站点应用脚本,但是在dbo._MigrationHistory中,ContextKey是MyDbConigClass1。之后,当我尝试使用另一个DbMigrationConfiguration类的Add-Migration时,ContextKeys不匹配 - BOOM!
So when I make the initial migration script and start the site and the site applies the script it is ok but in the dbo._MigrationHistory the ContextKey is "MyDbConigClass1". After that when I try Add-Migration which uses another DbMigrationConfiguration class the ContextKeys does not match - BOOM!
解决方案:添加了相同的ContextKey =MyTenantDb在我的配置类和所有开始重新工作,因为类型名称不再涉及,但DbMigrator使用我的自定义ContextKey:)
The solution : Added the same ContextKey = "MyTenantDb" in both of my configuration classes and everything started to work again because the type names no longer got involved but the DbMigrator used my custom ContextKey :)
这篇关于Enity Framework 6.0.0.0:无法通过基于代码的迁移生成显式迁移的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!