【问题标题】:There is already an object named '__MigrationHistory' in the database数据库中已经有一个名为“__MigrationHistory”的对象
【发布时间】:2014-09-29 08:40:46
【问题描述】:

当我尝试在远程数据库上执行 SQLQuery(由 Update-Database -Verbose -f -Script 在 Visual Studio 本地生成)时,我看到 SQL Server Management Studio 返回以下错误:

消息 2714,第 16 级,状态 6,第 1 行

数据库中已经有一个名为“__MigrationHistory”的对象。

如何解决?

【问题讨论】:

  • 您尝试运行的脚本是什么?
  • 只有在脚本中包含“create table __MigrationHistory”命令时才会发生这种情况。可以?虽然我无法想象为什么 update-database 会这样做。
  • @BenjaminPaul 你想看看它的内容吗?如果是的话,我会放那个:)
  • @SachinKainth 所以我需要在查询时找到这样的命令?然后删除?应该这样解决?
  • 您可能想在 nuget PM 中尝试以下命令:add-migration 以及 update-database

标签: c# entity-framework asp.net-mvc-5 nuget database-migration


【解决方案1】:

只是一个问题。您是否使用 dbo 以外的其他架构?

我认为这是 EF 框架中的一个错误,它在检查 __MigrationHistory 表是否存在时不检查架构。

我能够通过使用 dbo 架构创建一个 Dummy __MigrationHistory 表来解决这个问题,这欺骗了 EF6 生成器“创建表”

CREATE TABLE [dbo].[__MigrationHistory] ( [MigrationId] [nvarchar](150) NOT NULL, [ContextKey] [nvarchar](300) NOT NULL, [Model] [varbinary](max) NOT NULL, [ProductVersion] [nvarchar](32) NOT NULL, CONSTRAINT [PK_dbo.__MigrationHistory] PRIMARY KEY ([MigrationId], [ContextKey]) )

如果您想自动化它,您必须使用一个使用 dbo 架构的虚拟类创建一个空迁移,并首先运行该迁移以生成相关表。然后使用不同的架构运行迁移脚本,它应该可以工作。

【讨论】:

  • 这拯救了我的一天。两年多后我使用 EF 6.1.3 并且遇到了这个问题。如果我创建一个虚拟 __MigrationHistory 表,问题就会消失。我不敢相信还没有 6.1.4 可以解决这个问题!
  • 今天仍在 6.2.0 中出现
【解决方案2】:

__MigrationHistory 是一个自动生成的表,EF 使用它来跟踪它已应用于数据库的升级/补丁。 EF 完全了解该表并自行处理它。您不应该创建/删除/更改该表。您的数据库似乎已经有该表。如果 EF 或您的升级脚本尝试创建这样的表,这很奇怪。您需要仔细检查所有内容并猜测/了解到底发生了什么,因为要么 EF 变得疯狂,要么您的脚本准备方式错误。

【讨论】:

  • @MahmoudHboubati:感谢您纠正这个错字!我知道很难修复单个字母的错误,因为该网站需要更大的更改,但在这种情况下,您可以随时添加评论,例如“嘿,您在 foobar 中有错字”,并且作者会更正它。您真的不应该通过用逗号随机替换点或删除空格来损坏文本。
  • 虽然这个答案提供了丰富的信息,但它没有帮助,也不允许任何人解决问题。
  • @TravisO:这部分是正确的,但这是我们在没有更多信息的情况下所能得到的。除了一些非常奇特的事情,例如严重损坏的数据库服务器安装之外,这是唯一典型的可能情况:“那个脚本是错误的”,所以他必须双重或三重检查脚本以了解它为什么确实尝试创建这个表(而来自 EF 的脚本通常不会)。这很明显,但是 OP 有这个脚本,并没有说他尝试过查看它,也没有问为什么该脚本的某些部分尝试创建表,所以..我/我们还能建议他什么?
【解决方案3】:

我在执行“现有数据库中的代码优先”时看到了这种情况,其中提取的数据库已经具有 __MigrationHistory 表。

它最终添加了一个 POCO 类型的类。删除类,重做迁移并再次运行。

【讨论】:

    【解决方案4】:

    您应该将启动项目的连接字符串更改为指向远程数据库 - 它似乎指向已具有 __MigrationHistory 表的数据库,或者使用生成完整脚本

    update-database -script -SourceMigration $InitialDatabase
    

    它将所有迁移脚本写入一个文件并通过迁移检查迁移以查看需要运行哪些迁移。这个脚本做的第一件事是检查 __MigrationHistory 表是否存在,如果不存在就创建它。

    【讨论】:

      【解决方案5】:

      可能缺少迁移设置。按照this tutorial 中的建议,在更新数据库之前在包管理器控制台中键入命令add-migration MigrationName 对我有用。

      【讨论】:

      • True :),但是当我使用相同的命令创建迁移设置时,就会发生这种情况!它看起来与 EF 自动迁移相关的某些东西没有正常工作,并导致生成 SQL 命令来重新创建 __MigrationHistory 表,而不是更新!
      • 好的。所以我希望我的回答对其他人有用,因为我没有在您的问题的 cmets 中看到 jbutler483。
      【解决方案6】:

      删除数据库后,web.config 中连接字符串中的更改数据库名称解决了我的问题。这是一种有助于开发环境的解决方法。使用新实体重新创建了数据库。

      【讨论】:

        【解决方案7】:

        我从 Visual Studio 打开 SQL Explorer 并连接到数据库。直接使用 SQL 删除表。已删除迁移文件夹。再次运行迁移。因为它是测试数据库,所以删除表没有什么大问题。如果它有数据,则需要考虑不同的解决方案。没有其他工作。

        1. 工具 > SQL Server > 新查询
        2. 删除表“table_name”;
        3. 解决方案资源管理器 > 右键单击​​迁移并删除
        4. 工具 > Nuget 包管理器 > 包管理器控制台
        5. 在包管理器控制台中(通常在屏幕底部打开):Add-Migration InitialCreate4
        6. 更新数据库

        【讨论】:

          【解决方案8】:

          如果您正在使用带有 EF 和 .net 核心的现有数据库,那么在撰写本文时,您需要使用空的 Up/Down 方法(手动删除代码)创建初始迁移 (dotnet ef database update),因为 -IgnoreChanges 是未实施:

          protected override void Up(MigrationBuilder migrationBuilder)
                  {
          
                  }
          
                  protected override void Down(MigrationBuilder migrationBuilder)
                  {
                     
                  }
          

          这将阻止您的迁移尝试在代码优先方案中的第一次迁移中正常创建表。

          运行

          dotnet ef database update

          完成后,您将能够使用正常迁移进行更新。

          见: https://docs.microsoft.com/en-us/ef/ef6/modeling/code-first/migrations/existing-database

          What is the equivalent of the -IgnoreChanges switch for entity-framework core in CLI?

          【讨论】:

            【解决方案9】:

            转到迁移文件夹。 您将看到两个文件,一个是配置文件,另一个文件以 019763632 之类的数字开头...打开它 注释生成已创建表的代码。然后启用自动迁移Enable-Migrations -EnableAutomaticMigrations update-database 这对我有用,试试吧

            【讨论】:

              【解决方案10】:

              我设法通过删除确保创建数据库的部分来解决此错误。

              //Database.EnsureCreated();

              如果它不存在,这部分应该创建数据库。

              【讨论】:

              • 这个语句不可能抛出 OP 的异常。它所做的第一件事是检查数据库是否存在,如果存在则什么也不做。 OP的数据库显然存在。而当数据库不存在时,EF 肯定不会尝试两次添加__MigrationHistory
              猜你喜欢
              • 2019-05-12
              • 2011-03-29
              • 2016-04-08
              • 2014-08-01
              • 2010-11-12
              • 2021-05-10
              • 2013-10-21
              • 2020-10-19
              • 2016-06-22
              相关资源
              最近更新 更多