在 ASP.NET Core 3.1 中扩展 IdentityUser 后如何修复 EF Core 数据库错误?

How to fix EF Core database errors after extending IdentityUser in ASP.NET Core 3.1?

我在 ASP.NET Core 3.1 中构建了一个 Web 应用程序,同时也使用 Entity Framework Core 3.1,现在正尝试将其发布到 Azure。但是,在开发阶段,当我使用自定义 ApplicationUser class 扩展内置 IdentityUser class 时,我的 EF 迁移停止发布到数据库。已成功创建迁移,但更新数据库命令总是失败。

因为我无法理解错误消息,所以我只是根据每个后续迁移文件中包含的信息手动更新了数据库表。这在开发过程中运行良好,但现在我想将应用程序发布到 Azure,同样的错误导致应用程序无法在 Azure 上托管。

基本上,当 Azure 尝试创建数据库时,我 运行 在开发过程中遇到的完全相同的错误阻止了数据库的成功创建。而且因为我在开发过程中使用了手动解决方法,所以在尝试将应用程序发布到 Azure 时,我现在不知道如何解决错误。

以下是我在尝试发布到 Azure 时收到的错误消息:

System.AggregateException:出现一个或多个错误。 ---> System.Exception: 构建失败。检查输出 window 了解更多详细信息。 --- 内部异常堆栈跟踪结束 --- 在 System.Threading.Tasks.Task.ThrowIfExceptional(布尔值 includeTaskCanceledExceptions) 在 System.Threading.Tasks.Task.Wait(Int32 毫秒超时,CancellationToken cancellationToken) 在 Microsoft.WebTools.Publish.PublishService.VsWebProjectPublish.<>c__DisplayClass43_0.b__3() 在 System.Threading.Tasks.Task`1.InnerInvoke() 在 System.Threading.Tasks.Task.Execute() --- 从抛出异常的先前位置开始的堆栈跟踪结束 --- 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) 在 Microsoft.Publish.Framework.ViewModel.ProfileSelectorViewModel.d__213.MoveNext() --->(内部异常 #0)System.Exception:构建失败。检查输出 window 了解更多详细信息。<---

System.Exception: 构建失败。检查输出 window 了解更多详细信息。

===================

严重性代码说明项目文件行抑制状态 错误 Web 部署任务失败。 (在执行数据库脚本期间发生错误。错误发生在脚本的以下行之间:“568”和“581”。详细日志可能包含有关错误的更多信息。命令以以下内容开头: "IF NOT EXISTS(SELECT * FROM [__EFMigrationsHisto" 对象 'PK_AspNetUserTokens' 依赖于列 'Name'。 ALTER TABLE ALTER COLUMN Name 失败,因为一个或多个对象访问此列。 http://go.microsoft.com/fwlink/?LinkId=178587 Learn more at: http://go.microsoft.com/fwlink/?LinkId=221672#ERROR_SQL_EXECUTION_FAILURE.) 未能发布数据库。如果远程数据库无法 运行 脚本,就会发生这种情况。尝试修改数据库脚本,或在 Package/Publish Web 属性页面中禁用数据库发布。如果脚本由于数据库表已经存在而失败,请尝试在创建新数据库对象之前删除现有数据库对象。有关从 Visual Studio 执行这些选项的更多信息,请参阅 http://go.microsoft.com/fwlink/?LinkId=179181。 错误详情: 执行数据库脚本时出错。错误发生在脚本的以下行之间:“568”和“581”。详细日志可能包含有关错误的更多信息。该命令以以下内容开头: "IF NOT EXISTS(SELECT * FROM [__EFMigrationsHisto" 对象 'PK_AspNetUserTokens' 依赖于列 'Name'。 ALTER TABLE ALTER COLUMN Name 失败,因为一个或多个对象访问此列。 http://go.microsoft.com/fwlink/?LinkId=178587 Learn more at: http://go.microsoft.com/fwlink/?LinkId=221672#ERROR_SQL_EXECUTION_FAILURE。 对象 'PK_AspNetUserTokens' 依赖于列 'Name'。 ALTER TABLE ALTER COLUMN Name 失败,因为一个或多个对象访问此列。 在 System.Data.SqlClient.SqlConnection.OnError(SqlException 异常,Boolean breakConnection,Action1 wrapCloseInAction) at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action1 wrapCloseInAction) 在 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj,Boolean callerHasConnectionLock,Boolean asyncClose) 在 System.Data.SqlClient.TdsParser.TryRun(RunBehavior 运行Behavior,SqlCommand cmdHandler,SqlDataReader dataStream,BulkCopySimpleResultSet bulkCopyHandler,TdsParserStateObject stateObj,Boolean& dataReady) 在 System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(字符串方法名称、布尔异步、Int32 超时、布尔异步写入) 在 System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 完成,String methodName,Boolean sendToPipe,Int32 超时,Boolean& usedCache,Boolean asyncWrite,Boolean inRetry) 在 System.Data.SqlClient.SqlCommand.ExecuteNonQuery() 在 Microsoft.Web.Deployment.DBStatementInfo.Execute(DbConnection 连接,DbT运行saction t运行saction,DeploymentBaseContext baseContext,Int32 超时)BethanysPieShop 0

以下是我在开发过程中 运行 程序包管理器控制台中的更新数据库命令时遇到的相关错误:

fail: Microsoft.EntityFrameworkCore.Database.Command[20102]
      Failed executing DbCommand (1,684ms) [Parameters=[], CommandType='Text', CommandTimeout='120']
      DECLARE @var2 sysname;
      SELECT @var2 = [d].[name]
      FROM [sys].[default_constraints] [d]
      INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id]
      WHERE ([d].[parent_object_id] = OBJECT_ID(N'[AspNetUserTokens]') AND [c].[name] = N'Name');
      IF @var2 IS NOT NULL EXEC(N'ALTER TABLE [AspNetUserTokens] DROP CONSTRAINT [' + @var2 + '];');
      ALTER TABLE [AspNetUserTokens] ALTER COLUMN [Name] nvarchar(128) NOT NULL;
Failed executing DbCommand (1,684ms) [Parameters=[], CommandType='Text', CommandTimeout='120']
DECLARE @var2 sysname;
SELECT @var2 = [d].[name]
FROM [sys].[default_constraints] [d]
INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id]
WHERE ([d].[parent_object_id] = OBJECT_ID(N'[AspNetUserTokens]') AND [c].[name] = N'Name');
IF @var2 IS NOT NULL EXEC(N'ALTER TABLE [AspNetUserTokens] DROP CONSTRAINT [' + @var2 + '];');
ALTER TABLE [AspNetUserTokens] ALTER COLUMN [Name] nvarchar(128) NOT NULL;
Microsoft.Data.SqlClient.SqlException (0x80131904): The object 'PK_AspNetUserTokens' is dependent on column 'Name'.
ALTER TABLE ALTER COLUMN Name failed because one or more objects access this column.
   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 contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabaseImpl(String targetMigration, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabase.<>c__DisplayClass0_0.<.ctor>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
ClientConnectionId:a2c8216d-8ba5-413c-8ab8-1526fdb7a7e7
Error Number:5074,State:1,Class:16
The object 'PK_AspNetUserTokens' is dependent on column 'Name'.
ALTER TABLE ALTER COLUMN Name failed because one or more objects access this column.

我认为在这种情况下你能做的最好的事情是删除你的迁移,如果你把所有的东西都设置在你想要的地方,擦除你的数据库清理并从头开始迁移和数据库。

我知道这不是处理它的理想方式,但我认为你从迁移和更新数据库开始,然后转向使用迁移脚本手动更新数据库,这会很困难而且几乎不可能把它放回你需要的地方。

通过新的迁移,您所有的表都应该正确无误地设置。

来源:我做了和你完全一样的事情,现在我非常小心地处理迁移并确保正确应用它们,我没有更多的问题。

如果您正在使用迁移和更新数据库,请坚持使用,我不会用脚本手动完成