ChatGPT解决这个技术问题 Extra ChatGPT

实体框架回滚并移除不良迁移

我在 C# 中为我的项目使用 EF 6.0,并进行手动迁移和更新。我在数据库上进行了大约 5 次迁移,但我意识到最后一次迁移很糟糕,我不想要它。我知道我可以回滚到以前的迁移,但是当我添加一个新的(固定的)迁移并运行 Update-Database 时,即使是错误的迁移也会被应用。

我试图回滚到以前的迁移并删除迁移错误的文件。但是,当我尝试添加新迁移时,更新数据库时出现错误,因为迁移文件已损坏(更具体地说,第一行代码将表 A 重命名为 B 并且是下一行,EF 正在尝试更新表名称 A - 可能是一些 EF 错误)。

是否有一些我可以运行的查询,它会告诉 EF 类似“忘记上次迁移,就像它从未存在过一样,这很糟糕”?像移除迁移这样的东西。

Edit1 我找到了适合我的解决方案。将模型更改为良好状态并运行 Add-Migration TheBadMigration -Force。这将重新构建最后一个未应用的迁移。

无论如何,这仍然不能完全回答原来的问题。如果我将 UpdateDatabase 迁移到错误的迁移,我没有找到如何回滚和创建新迁移的好方法,不包括错误的迁移。

谢谢

我不得不重新启动视觉工作室,然后它开始正常工作。这在我身上已经发生了几次,总是在没有实际更新数据库的情况下搞乱迁移之后,所以那里的工具发生了一些奇怪的事情。

N
Not loved

您有 2 个选项:

您可以从错误的迁移中取出 Down 并将其放入新的迁移中(您还需要对模型进行后续更改)。这有效地升级到更好的版本。我在已经进入多个环境的东西上使用这个选项。

另一种选择是针对您部署的数据库实际运行 Update-Database –TargetMigration: TheLastGoodMigration,然后从您的解决方案中删除迁移。这有点像 hulk 粉碎替代方案,需要针对使用错误版本部署的任何数据库执行此操作。注意:要重新构建迁移,您可以使用 Add-Migration [existingname] -Force。但是,这将覆盖您现有的迁移,因此请务必仅在您已从数据库中删除现有迁移时执行此操作。这与删除现有迁移文件并运行 add-migration 的作用相同,我在开发时使用此选项。


绿巨人粉碎选项不起作用。我还没有将错误的迁移应用到数据库。我试过了,但它不起作用,因为我在原始问题中指定的表名。第一个选项我不太喜欢,因为看起来我必须更改迁移代码。如果我做得不好,我可以打破它。
如果您尚未应用错误的迁移,则没有什么能阻止您删除它并重新搭建或纠正损坏的迁移。
“绿巨人粉碎”就是答案,它在开发时对我有用,我想为我错过的迁移添加一些东西。我认为它对 Martin 不起作用的原因是无关的(或者可能与手动更改数据库模式有关)
@BenRethmeier 作为一般规则,我仅在开发时才使用 hulk 粉碎选项。在产品中,我总是创建一个新的迁移来纠正这个问题。原因是在降级数据库时需要人工干预。我不喜欢任何需要手动干预产品的东西。
HULK SMASH !!!!--- 我试着表现得很好,但 EF 没有播放 - 我恢复到上次已知的 - (备份的迁移文件)删除,添加迁移 - 强制 - 重命名为以前的并复制代码。更新数据库然后添加第二次迁移以同样的方式 - 没有错误 - 恢复正常
D
David Sopko

正如问题所示,这适用于尚未发布的开发类型环境中的迁移。

这个问题可以通过以下步骤解决:

将您的数据库恢复到上次良好的迁移。从您的 Entity Framework 项目中删除错误的迁移。生成新的迁移并将其应用于数据库。

注意:Entity Framework 和 Entity Framework Core 使用的命令名称略有不同

第 1 步:恢复到以前的迁移

如果您尚未应用迁移,则可以跳过此部分。要将数据库模式恢复到前一点,请发出带有 -TargetMigration 选项的 Update-Database 命令以指定最后一次良好的迁移。对于 EFCore,使用更新数据库“迁移名称”

如果您的实体框架代码位于解决方案中的不同项目中,您可能需要使用“-Project”选项或在包管理器控制台中切换默认项目。

Update-Database –TargetMigration: <name of last good migration>

对于 EFCore:

Update-Database <name of last good migration>

要获取最后一次良好迁移的名称,请使用“Get-Migrations”命令检索已应用于数据库的迁移名称列表,如果您使用的是 EFCore,请使用不带“s”的“Get-Migration”。

PM> Get-Migrations
Retrieving migrations that have been applied to the target database.
201508242303096_Bad_Migration
201508211842590_The_Migration_applied_before_it
201508211440252_And_another

此列表首先显示最近应用的迁移。选择列表中您要降级到的迁移之后发生的迁移,即在您要降级的迁移之前应用的迁移。现在发出一个更新数据库。

Update-Database –TargetMigration: "<the migration applied before it>"

对于 EFCore:

Update-Database "<the migration applied before it>"

在指定迁移之后应用的所有迁移都将按照从最先应用的最新迁移开始的顺序降级。

如果您的降级可能导致数据丢失,EF 将拒绝该命令。使用“-Force”选项接受数据丢失并允许执行命令。

第 2 步:从项目中删除您的迁移

如果您使用的是 Entity Framework Core,则可以使用“remove-migration”命令,对于 Entity Framework,手动删除 EF 项目“Migrations”文件夹中不需要的迁移文件。此时,您可以自由地创建一个新的迁移并将其应用到数据库。

对于 EFCore:

remove-migration name_of_bad_migration

第 3 步:添加新的迁移

add-migration my_new_migration

第 4 步:将迁移应用到数据库

update-database

使用 EF Core,似乎 Get-Migrations 已被删除。
第2步 ! - 非常有用的功能。正如@KevinBurton 提到的。然后是 add-migration "new migration"update-database
Update-Database –migration:“<之前应用的迁移>”@David Sopko
使用 dotnet tool install --global dotnet-ef 安装 dotnet ef (EF Core 3.x) 后,我能够使用 dotnet-ef migrations list --project your-project-name 列出迁移。
我们需要在第 2 步之后使用 remove-migration
R
Richard Logwood

对于那些将 EF Core 与 ASP.NET Core v1.0.0 一起使用的人,我遇到了类似的问题,并使用以下命令进行了更正(@DavidSopko 的帖子为我指明了正确的方向,但 EF Core 的细节略有不同):

Update-Database <Name of last good migration>
Remove-Migration

例如,在我目前的开发中,命令变成了

PM> Update-Database CreateInitialDatabase
Done.
PM> Remove-Migration
Done.
PM> 

Remove-Migration 将删除您应用的最后一个迁移。如果您有一个更复杂的场景,需要删除多个迁移(我只有 2 个,最初的和坏的),我建议您在虚拟项目中测试这些步骤。

EF Core (v1.0.0) 目前似乎没有 Get-Migrations 命令,因此您必须查看迁移文件夹并熟悉您所做的事情。但是,有一个很好的帮助命令:

PM> get-help entityframework

在 VS2015 SQL Server 对象资源管理器中刷新数据库,我的所有数据都被保留了,我想要恢复的迁移已经消失了 :)

最初我自己尝试了 Remove-Migration 并发现错误命令令人困惑:

System.InvalidOperationException:迁移“...”已应用于数据库。取消应用并重试。如果迁移已应用于其他数据库,请考虑使用新迁移恢复其更改。

已经有改进此措辞的建议,但我希望错误说如下:

运行 Update-Database(最后一个好的迁移名称)以将数据库模式恢复到该状态。此命令将取消应用在指定到 Update-Database 的迁移之后发生的所有迁移。然后,您可以运行 Remove-Migration(要删除的迁移名称)

EF Core 帮助命令的输出如下:

 PM> get-help entityframework
                     _/\__
               ---==/    \\
         ___  ___   |.    \|\
        | __|| __|  |  )   \\\
        | _| | _|   \_/ |  //|\\
        |___||_|       /   \\\/\\

TOPIC
    about_EntityFrameworkCore

SHORT DESCRIPTION
    Provides information about Entity Framework Core commands.

LONG DESCRIPTION
    This topic describes the Entity Framework Core commands. See https://docs.efproject.net for information on Entity Framework Core.

    The following Entity Framework cmdlets are included.

        Cmdlet                      Description
        --------------------------  ---------------------------------------------------
        Add-Migration               Adds a new migration.

        Remove-Migration            Removes the last migration.

        Scaffold-DbContext          Scaffolds a DbContext and entity type classes for a specified database.

        Script-Migration            Generates a SQL script from migrations.

        Update-Database             Updates the database to a specified migration.

        Use-DbContext               Sets the default DbContext to use.

SEE ALSO
    Add-Migration
    Remove-Migration
    Scaffold-DbContext
    Script-Migration
    Update-Database
    Use-DbContext

该命令是“Get-Migration”而不是 Get-MigrationS。我花了一点时间才弄清楚!这是 EntityFrameworkCore.Tools 5.07。
D
Daniël Tulp

你也可以使用

Remove-Migration -Force

这将恢复并删除上次应用的迁移


G
Gert Arnold

我将 EF Core 与 ASP.NET Core V2.2.6 一起使用。 @Richard Logwood 的回答很棒,它解决了我的问题,但我需要不同的语法。

因此,对于那些将 EF Core 与 ASP.NET Core V2.2.6 + 一起使用的人...

代替

Update-Database <Name of last good migration>

我不得不使用:

dotnet ef database update <Name of last good migration>

而不是

Remove-Migration

我不得不使用:

dotnet ef migrations remove

对于 --help,我必须使用:

dotnet ef migrations --help


Usage: dotnet ef migrations [options] [command]

Options:
  -h|--help        Show help information
  -v|--verbose     Show verbose output.
  --no-color       Don't colorize output.
  --prefix-output  Prefix output with level.

Commands:
  add     Adds a new migration.
  list    Lists available migrations.
  remove  Removes the last migration.
  script  Generates a SQL script from migrations.

Use "migrations [command] --help" for more information about a command.

这让我的角色回到了我的数据库按预期工作的阶段,并从头开始。


EF Core 有一个 Remove-Migrationremove 命令。但如果您仍在使用 EF6,则 Remove-Migrationremove 命令不可用。
我在 EF Core 上,只能使用 remove
如果您只能使用 remove,那么您必须使用 dotnet CLI。 Remove-Migration 命令用于 Visual Studios IDE 的包管理控制台 (PMC)。
A
Abdus Salam Azad

首先,通过以下命令更新您的最后一次完美迁移:

Update-Database –TargetMigration

例子:

Update-Database -20180906131107_xxxx_xxxx

然后手动删除未使用的迁移。


它应该是:Update-Database -TargetMigration 20180906131107_xxxx_xxxx
Update-Database 20180906131107_xxxx_xxxx(无连字符)对我有用。没有任何版本的 TargetMigration 作为开关起作用。这些命令似乎是一个移动的目标(即在每个版本中更改它们)?
S
Sum None

从 .NET Core 2.2 开始,TargetMigration 似乎消失了:

get-help Update-Database

NAME
    Update-Database

SYNOPSIS
    Updates the database to a specified migration.


SYNTAX
    Update-Database [[-Migration] <String>] [-Context <String>] [-Project <String>] [-StartupProject <String>] [<CommonParameters>]


DESCRIPTION
    Updates the database to a specified migration.


RELATED LINKS
    Script-Migration
    about_EntityFrameworkCore 

REMARKS
    To see the examples, type: "get-help Update-Database -examples".
    For more information, type: "get-help Update-Database -detailed".
    For technical information, type: "get-help Update-Database -full".
    For online help, type: "get-help Update-Database -online"

所以这对我有用:

Update-Database -Migration 20180906131107_xxxx_xxxx

以及(没有 -Migration 开关):

Update-Database 20180906131107_xxxx_xxxx

另外需要注意的是,如果不使模型快照不同步,您将无法再干净地删除迁移文件夹。因此,如果您以艰难的方式学习这一点并以一个空迁移结束,您知道应该有更改,您可以运行(上次迁移不需要开关):

Remove-migration

即使手动删除了最后一个迁移文件夹,它也会清理混乱并让您回到需要的位置。


M
Michael Adamission

对于 EF 6,如果您在开发中大量重新搭建脚手架,那么这里是单线。只需更新变量,然后继续使用包管理器控制台中的向上箭头来冲洗并重复。

$lastGoodTarget = "OldTargetName"; $newTarget = "NewTargetName"; Update-Database -TargetMigration "$lastGoodTarget" -Verbose; Add-Migration "$newTarget" -Verbose -Force

你问为什么这有必要?不确定这适用于哪个版本的 EF6,但如果您的新迁移目标已经应用,那么在 Add-Migration 中使用“-Force”重新构建脚手架实际上不会重新构建脚手架,而是制作一个新文件(这是一个很好的不过,因为你不想失去你的“失望”)。如有必要,上面的代码片段首先执行“向下”,然后 -Force 正常工作以重新搭建脚手架。


D
Dharman

确保您在项目文件中没有错误,即使在您的迁移文件中,我在上一个迁移文件中也有错误并且不允许我将其删除。