【问题标题】:How to manually (via code) apply DbMigration which was manually crafted?如何手动(通过代码)应用手动制作的 DbMigration?
【发布时间】:2017-04-12 14:49:48
【问题描述】:

我手动创建了一个类

  public class AddClientsTable : DbMigration, IMigrationMetadata
  {
        
    string IMigrationMetadata.Id
    {
      get { return "201611281757258_AddClientsTable"; }
    }

    string IMigrationMetadata.Source
    {
      get { return null; }
    }

    string IMigrationMetadata.Target
    {
      get { return "AddClientsTable-Migration"; }
    }

    public override void Up() {
      CreateTable("Clients", t => new {
          ClientId = t.Guid(name:"ClientId"),
          Name = t.String()
          })
      .PrimaryKey( t => t.ClientId, "ClientId")
      .Index( t => t.ClientId, "PK_Clients", true);
    }

    public override void Down() {
      DropIndex("Clients", "PK_Clients");
      DropTable("Clients");
    }

  }

我想通过代码优先迁移从代码应用它:

      var migration = new AddClientsTable();
      migration.Up();
      context.RunMigration(migration);

这是我从here 偷来的,但是当我运行代码时,我得到了这个异常:

Unable to cast object of type 'System.Data.Entity.Migrations.Model.CreateIndexOperation' to type 'System.Data.Entity.Migrations.Model.HistoryOperation'.

HistoryOperation 是更新__MigrationHistory 表的操作?那么我该如何通过代码做到这一点?

我是否遗漏了什么或者 EntityFrameowrk Update-Database 命令比我知道的更多?

【问题讨论】:

  • 你为什么又要通过代码来做呢?
  • 好吧,我不使用visual studio(在我很旧的机器上太慢)执行Update-Database命令,我只是使用gvim进行代码编辑,我真的很想能够做到Code-First 数据库迁移就是这样。
  • 你有powershell吗?实体框架的每个数据库函数都有 powershell 命令
  • 是的,我在 Windows 上,我确实有 powershell,但是需要在代码中执行它的原因是我需要在我的用户机器上应用相同的迁移,所以它会是更容易迁移他们的本地数据库。
  • 如果您想先使用代码执行所有新迁移,请尝试MigrateDatabaseToLatestVersion msdn.microsoft.com/en-us/library/…(此处为示例github.com/tym32167/arma3beclient/blob/master/src/…

标签: c# entity-framework-6 dbmigrate


【解决方案1】:

挑选一个迁移并运行它是没有意义的,因为迁移是累积的,必须按顺序运行。因此,您最好在应用程序启动时运行相当于update-database powershell 命令。

以下是我们用来执行此操作的一些代码:

Configuration.cs类构造函数中(这个文件是你enable-migrations时创建的)

AutomaticMigrationsEnabled = false;
AutomaticMigrationDataLossAllowed = false;

然后在应用启动时调用以下方法:

public static void ApplyDatabaseMigrations()
{
    //Configuration is the class created by Enable-Migrations
    DbMigrationsConfiguration dbMgConfig = new Configuration()
    {
        ContextType = typeof(MyDbContext) //+++++CHANGE ME+++++
    };
    using (var databaseContext = new MyDbContext()) //+++++CHANGE ME+++++
    {
        try
        {
            var database = databaseContext.Database;
            var migrationConfiguration = dbMgConfig;
            migrationConfiguration.TargetDatabase =
                new DbConnectionInfo(database.Connection.ConnectionString,
                                     "System.Data.SqlClient");
            var migrator = new DbMigrator(migrationConfiguration);
            migrator.Update();
        }
        catch (AutomaticDataLossException adle)
        {
            dbMgConfig.AutomaticMigrationDataLossAllowed = true;
            var mg = new DbMigrator(dbMgConfig);
            var scriptor = new MigratorScriptingDecorator(mg);
            string script = scriptor.ScriptUpdate(null, null);
            throw new Exception(adle.Message + " : " + script);
        }
    }
}

【讨论】:

  • 尝试了您的解决方案,但遇到了另一个问题,` string IMigrationMetadata.Target { get { return "AddClientsTable-Migration"; } }`这个字段需要是模型的Base64(?),我怎样才能从代码或powershell生成它?我正在考虑使用命令行中的 powershell 来生成迁移并使用 yoyr 代码片段应用它们。
  • @Abdelghani 这就是Add-Migration 命令的用途。祝你在没有它的情况下顺利完成迁移。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-06
  • 2014-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-25
  • 2011-05-14
相关资源
最近更新 更多