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

Kel*_*ele 4 c# sql database entity-framework-core asp.net-core

我是通过命令行更新我的数据库,但后来我手动更新了我的一个表.

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

 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. 
Run Code Online (Sandbox Code Playgroud)

过去几天我一直试图解决这个问题.大多数开发人员建议使用添加迁移"重置"-IgnoreChanges的一些变体,如以下链接中的 John Salewski .

但是,我不断收到一条错误消息"无法找到与参数名称'IgnoreChanges'匹配的参数".

任何建议将不胜感激!

Ste*_*ene 12

首先,这不是EF 6,它是EF Core.目前EF Core中没有-IgnoreChanges(参见此处),但您可以通过注释Up()方法中的所有代码并应用迁移来实现等效.这将拍摄当前模型状态的快照,以便后续迁移仅包括从该点开始的更改.

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

  • 好的,没有意识到您以前有迁移。因此,这听起来像是您手动将ClientsAndTestimonials添加到数据库中,而不是让迁移创建数据库,所以现在当您将其添加到模型中时,EF会尝试再次添加它。应用相同的概念-查看您的Up()代码并注释掉创建已存在对象的行。只要已部署所有部署,您就可以始终[重置迁移](https://weblog.west-wind.com/posts/2016/jan/13/reset-entity-framework-migrations-to-a-clean-slate)数据库到此为止。 (2认同)

小智 7

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

在 EF 6 中,此问题通过使用 -IgnoreChanges 标志得到解决。此处对此进行了描述。

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

场景 1.

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

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

public MyContext(DbContextOptions<MyContext> options) : base (options)
{
    Database.EnsureDeleted();
    Database.EnsureCreated();
}
Run Code Online (Sandbox Code Playgroud)

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() 时,更新数据库步骤时会出现“数据库中已存在名为“实体名称”的对象。”错误。正如 Steve Green 所说,我们可以使用 Up 和 Down 方法删除所有生成的代码。它会很有用,但我们必须在数据模型发生所有变化之后才这样做