Enity Framework 6.0.0.0:无法通过基于代码的迁移生成显式迁移 [英] Enity Framework 6.0.0.0 : Unable to generate an explicit migration... with Code-based migration

查看:1927
本文介绍了Enity Framework 6.0.0.0:无法通过基于代码的迁移生成显式迁移的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

情况是:


  1. 每租户数据库。

  2. 非自动基于代码基于迁移。 dbs的初始创建也是通过Code First。目前情况下没有预先存在的dbs。

  3. 在生成迁移脚本期间,确切的数据库不知道,因为有很多。我唯一需要的是代码 - 初始迁移脚本基于初始模型和模型进行了一些修改。

  4. 使用初始脚本生成的现有dbs - 一切正常。以下是我如何重现问题:

  5. 运行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 - 工作正常

  6. 运行应用程序并创建数据库。停止应用程序修改模型。

  7. 运行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。

  8. - 迁移者甚至不连接到MSSQL来检查数据库是否存在或具有dbo .__MigrationHistory!我已经进一步关闭了MSSQL服务! - 如果输入虚拟数据库名称或关闭整个MSSQL服务器无关紧要 - 错误是相同的,没有连接。那么当它不检查数据库时,它如何知道迁移正在等待?我假设一个bug。

  9. 我已经创建了__dbo.MigrationHistory,其中已初始化迁移。

  10. 错误:无法生成显式迁移,因为以下显式迁移待处理:[201402121953301_Initial]。在尝试生成新的显式迁移之前应用挂起的显式迁移。

  1. Per tenant db.
  2. 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.
  3. 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.
  4. Existing dbs generated with initial script - everything works fine. Here is how I reproduce the problem :
  5. 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
  6. Run the app and the db is created. Stop the app. Make modification to the model.
  7. 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.
  8. 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.
  9. I have __dbo.MigrationHistory created already with the Initial migration in it.
  10. 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.


  1. 在EntityFramework.dll里面有一个类

  2. System.Data.Entity.Migrations.DbMigrator用一个方法

  3. 脚手架(string migrationName,string @namespace,bool ignoreChanges)

  4. 哪个拨打这个.GetPendingMigrations

  5. 哪个方法在另一个类上调用另一个方法 HistoryRepository.CreateHistoryQuery (HistoryContext context,string contextKey = null),参数contextKey == NULL

  6. 但是这种方法里面有这样的情况

  1. Inside EntityFramework.dll there is the class
  2. System.Data.Entity.Migrations.DbMigrator with a method
  3. Scaffold(string migrationName, string @namespace, bool ignoreChanges)
  4. Which makes a call this.GetPendingMigrations
  5. Which method calls another method on another class HistoryRepository.CreateHistoryQuery(HistoryContext context, string contextKey = null) with the parameter contextKey == NULL
  6. 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


  1. 我使用两个不同的DbMigrationConfiguration类

  2. ,因为迁移程序集与应用程序的核心分开,使得

  3. 它们有两种不同的完全限定命名类,最终

  4. 导致两个不同的ContextKey在用于生成迁移脚本的DbMigrationConfiguration的dbo._MigrationHistory表中。

  1. I use two different DbMigrationConfiguration classes
  2. because the migration assembly is separated from the core of the application which makes
  3. them two differently 'fully qualified named classes' which at the end
  4. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆