首页 > 解决方案 > 如何修复数据库中已经存在名为“Books”的对象

问题描述

我创建了小型 Web API,但是当我要将模型类迁移到物理数据库时,它给了我一个错误。我给的时候项目没问题Add-Migration。当我尝试给予时会发生此错误Update-Database

Build started...
Build succeeded.
fail: Microsoft.EntityFrameworkCore.Database.Command[20102]
      Failed executing DbCommand (111ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      CREATE TABLE [Books] (
          [Id] int NOT NULL IDENTITY,
          [Title] nvarchar(100) NULL,
          [Author] nvarchar(100) NULL,
          [Description] nvarchar(100) NULL,
          CONSTRAINT [PK_Books] PRIMARY KEY ([Id])
      );
Failed executing DbCommand (111ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE [Books] (
    [Id] int NOT NULL IDENTITY,
    [Title] nvarchar(100) NULL,
    [Author] nvarchar(100) NULL,
    [Description] nvarchar(100) NULL,
    CONSTRAINT [PK_Books] PRIMARY KEY ([Id])
);
Microsoft.Data.SqlClient.SqlException (0x80131904): There is already an object named 'Books' in the database.
   at Microsoft.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at Microsoft.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at Microsoft.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at Microsoft.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at Microsoft.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean isAsync, Int32 timeout, Boolean asyncWrite)
   at Microsoft.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, Boolean sendToPipe, Int32 timeout, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry, String methodName)
   at Microsoft.Data.SqlClient.SqlCommand.ExecuteNonQuery()
   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteNonQuery(RelationalCommandParameterObject parameterObject)
   at Microsoft.EntityFrameworkCore.Migrations.MigrationCommand.ExecuteNonQuery(IRelationalConnection connection, IReadOnlyDictionary`2 parameterValues)
   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.Internal.MigrationsOperations.UpdateDatabase(String targetMigration, String connectionString, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabaseImpl(String targetMigration, String connectionString, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabase.<>c__DisplayClass0_0.<.ctor>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
ClientConnectionId:0b41a251-3fe9-4c55-a2fd-118e7348a564
Error Number:2714,State:6,Class:16
There is already an object named 'Books' in the database.

在我的 SQL Server 数据库中,没有名为“Books”的表。为什么我会收到此错误,我该如何解决?

标签: c#asp.netsql-serverentity-frameworkasp.net-core

解决方案


当您更新内容然后尝试删除文件或对象而不尝试正确还原上下文时,可能会发生此类事情。下面我将介绍解决此问题或您可能遇到的问题的方法。

解决方案 1 - 删除它

这种方法是我用来清除我犯了错误的表上的冲突并且更新它并不是一个真正的选择。但在您更好地了解 EF 的工作原理之前,我不会推荐这种方法。

当 EF 说对象已经存在时 - 它可能不是指表,而是在您的迁移文件之一中定义的对象。但是要完全(手动)清除对象,您需要做两件事:

  1. 删除项目中可能定义 book 的迁移文件。
  2. 删除数据库中的迁移记录(是的,有一个表)。

解决方案 2 - 还原它

这是推荐的,我会说 EF 核心的新手应该使用:

使用以下命令恢复您的迁移:Update-Database <prior-migration-name>Books在定义对象之前选择较早的迁移之一。然后再次更新迁移,它应该可以工作 - 如果您没有DbSet<Books>在上下文中定义两次。

解决方案 3 - 顺其自然

初学者使用的另一种方法是使用脚手架从数据库中下载上下文。这将下载您正在使用的数据库以及其中的所有对象 - 然后您可以根据需要在其中更改它。

Scaffold-DbContext "<Connection String>" Microsoft.EntityFrameworkCore.SqlServer -OutputDir <Directory>

使用此方法时要小心,它可以替换您当前的上下文。

建议

我会说先使用方法2,如果那不起作用,然后使用方法1,最后使用方法3。


推荐阅读