Update-Database 命令在 ASP.Net Core / Entity Framework Core 中不起作用,因为数据库中的对象已经存在

Posted

技术标签:

【中文标题】Update-Database 命令在 ASP.Net Core / Entity Framework Core 中不起作用,因为数据库中的对象已经存在【英文标题】:Update-Database command is not working in ASP.Net Core / Entity Framework Core because object in database already exists 【发布时间】:2017-04-28 19:17:00 【问题描述】:

我正在通过命令行更新我的数据库,但后来我手动更新了我的一张表。

这似乎破坏了我更新数据库的能力。当我尝试更新时收到以下错误:

 System.Data.SqlClient.SqlException: There is already an object named 'ClientsAndTestimonials' in the database.    at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
    at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async, Int32 timeout, Boolean asyncWrite)
    at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite, String methodName)
    at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
    at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.Execute(IRelationalConnection connection, String executeMethod, IReadOnlyDictionary`2 parameterValues, Boolean openConnection, Boolean closeConnection) 
    at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.ExecuteNonQuery(IRelationalConnection connection, IReadOnlyDictionary`2 parameterValues, Boolean manageConnection) 
    at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationCommandExecutor.ExecuteNonQuery(IEnumerable`1 migrationCommands, IRelationalConnection connection) 
    at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate(String targetMigration) 
    at Microsoft.EntityFrameworkCore.Design.MigrationsOperations.UpdateDatabase(String targetMigration, String contextType) 
    at Microsoft.EntityFrameworkCore.Tools.Cli.DatabaseUpdateCommand.<>c__DisplayClass0_0.<Configure>b__0() 
    at Microsoft.Extensions.CommandLineUtils.CommandLineApplication.Execute(String[] args)
    at Microsoft.EntityFrameworkCore.Tools.Cli.Program.Main(String[] args)
 ClientConnectionId:d89989a8-ce8b-4167-be7e-fcddc4bcdf98
 Error Number:2714,State:6,Class:16
 There is already an object named 'ClientsAndTestimonials' in the database. 

过去几天我一直在尝试解决这个问题。大多数开发人员建议使用 Add-migration "Reset" -IgnoreChanges 的一些变体,例如来自以下link 的 John Salewski。

但是,我不断收到一条错误消息,提示“找不到与参数名称 'IgnoreChanges' 匹配的参数”。

任何建议将不胜感激!

【问题讨论】:

试试 -Ignore_Changes 你在数据库中有你需要的任何数据吗,如果不只是删除整个数据库并重新添加它 @WEI_DBA,这不起作用,我遇到了同样的错误。还有其他想法吗? @johnny5 我在数据库中有很多数据。还有什么我可以做的,让我保留数据吗? @KelseySteele 我相信史蒂夫格林的回答应该有效 【参考方案1】:

EF Core 中目前没有 -IgnoreChanges(请参阅 here),但您可以通过注释掉 Up() 方法中的所有代码并应用迁移来实现等效。这将拍摄当前模型状态的快照,以便后续迁移仅包含从该点开始的更改。

因此,如果您只是进行了一些增量模型更改并且您没有此初始基准,您可能需要删除这些更改,应用基准迁移,然后添加您的更改并添加第二次迁移。

【讨论】:

我仍然遇到同样的错误。我不确定我的顺序是否正确。 Up() 方法在迁移中。所以我必须首先创建一个新的迁移才能看到 Up() 方法,但我认为这是在创建快照,或者至少我是这样认为的,因为它被称为 ApplicationDbContextModelSnapshot。我看不出如何在不创建包含后续迁移的快照的情况下注释掉 Up() 方法。我应该删除我以前的所有迁移吗? 好的,没有意识到您之前进行过迁移。因此,听起来您手动将 ClientsAndTestimonials 添加到数据库中,而不是让迁移创建它,所以现在当您将其添加到模型时,EF 会尝试再次添加它。同样的概念适用 - 查看您的 Up() 代码并注释掉创建已存在对象的行。只要所有已部署的数据库都达到这一点,您就可以随时reset migrations。 谢谢你,史蒂夫!这似乎奏效了。我按照您的链接中的说明重置迁移,现在我可以更新数据库。非常感谢您的帮助。 我是否应该评论我的第一个(内部项目)上下迁移以获得基本模型快照? 是的。代码中存储在资源字段中的模型是关键。它用于进行下一次比较(数据库记录不是)。另外,如果您启动一个新数据库,它仍然会创建所有对象,因为它会将空模型与存储模型进行比较。【参考方案2】:

在 up() 函数中使用 Alter 列代替 AddColumn

    migrationBuilder.AlterColumn<bool>(
        name: "IsActive",
        table: "Advertisements",
        nullable: false,
        defaultValue: true);

或者

      public override void Up()
      
        AddColumn("dbo.Products", "Description", c => c.String(maxLength: 50));
      

asp.net 迁移

如果您不想完全影响数据库,您可以在 up 功能中备注某些部分。

如果您的迁移命令对制作这些内容感到愤怒。重置和变基迁移。如何: 再次从 visualstudio 和 sql 和 add-migrationupdate-database 删除迁移内容

【讨论】:

【参考方案3】:

答案:不要同时使用Update-Database 和Database.EnsureCreated()。

在 EF 6 中,通过使用 -IgnoreChanges 标志解决了这个问题。这被描述为here。

EF Core 5 中没有 -IgnoreChanges 标志,EF Core 5 中有两种迁移场景。

场景 1。

在开发的早期,我们可以使用一对方法:Database.EnsureDeleted() 和Database.EnsureCreated()。

所以我们应该在上下文构造函数中使用这些方法,例如:

public MyContext(DbContextOptions<MyContext> options) : base (options)

    Database.EnsureDeleted();
    Database.EnsureCreated();

EnsureDeleted() 方法将删除我们的数据库。 EnsureCreated() 方法将重新创建我们的数据库。存储在数据库中的所有数据都将丢失。请注意,EnsureDeleted() 和 EnsureCreated() 仅在我们的数据模型发生更改时才有效。

这种情况适用于开发的早期阶段,此时我们可以允许在更改数据模型后在每个正在运行的应用程序上重新创建数据库。

场景 2。

我们也可以使用手动更新数据库。为此,我们需要在包管理器中使用 Add-Migration 和 Update-Database。

添加迁移后,EF 工具使用方法 void Up (MigrationBuilder migrationBuilder) 和 void Down (MigrationBuilder migrationBuilder) 创建一个新的迁移类。

之后,我们应该使用 Update-Database,它允许我们更改我们的数据库。

当我们同时使用 Add-Migration-Update-Database 和 EnsureDeleted()-EnsureCreated() 时,我们在更新数据库步骤时得到“数据库中已经有一个名为 'Entity name' 的对象。”错误。 As Steve Green said,我们可以使用 Up 和 Down 方法删除所有生成的代码。它会很有用,但我们必须在数据模型发生所有变化后才这样做

【讨论】:

【参考方案4】:

对此有帮助:

    注释掉初始迁移文件的所有 Up() 方法 运行应用程序 然后在 EFMigrationsHistory 的数据库中生成第一个条目 我把 Up() 方法改回原来的了 再次运行应用程序,错误消失了

在本地和服务器上为我工作。

【讨论】:

【参考方案5】:

错误号:2714,状态:6,类:16 数据库中已经有一个名为“Employee”的对象。

我刚刚解决了 go to up 方法的 Migration 和 Comment the Employee code 这是跟随

migrationBuilder.CreateTable(
                name: "Employee",
                columns: table => new
                
                    Eid = table.Column<int>(type: "int", nullable: false),
                    FirstName = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false),
                    LastName = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false),
                    Salary = table.Column<decimal>(type: "money", nullable: false),
                    Gender = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: true),
                    Did = table.Column<int>(type: "int", nullable: true),
                    Email = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: true),
                    ConfirmEmail = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: true),
                    LnKdProfile = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: true)
                ,
                constraints: table =>
                
                    table.PrimaryKey("PK_Employee", x => x.Eid);
                );

步骤:然后我运行 update-database 命令,它成功运行它给出错误,因为 Employee 表已经存在于我的数据库中,所以我们无法创建具有相同名称的新表。

【讨论】:

以上是关于Update-Database 命令在 ASP.Net Core / Entity Framework Core 中不起作用,因为数据库中的对象已经存在的主要内容,如果未能解决你的问题,请参考以下文章

Update-Database 命令在建立与服务器的连接时出错(代码优先迁移)

Update-Database 命令在 ASP.Net Core / Entity Framework Core 中不起作用,因为数据库中的对象已经存在

无法将“Update-Database”项识别为 cmdlet函数脚本文件或可运行程序的名称的问题

ABP框架数据迁移报错

Update-Database - (localdb) MSSQLLocalDB出错

切换分支时如何解决Update-Database问题?