我在 C# 中为我的项目使用 EF 6.0,并进行手动迁移和更新。我在数据库上进行了大约 5 次迁移,但我意识到最后一次迁移很糟糕,我不想要它。我知道我可以回滚到以前的迁移,但是当我添加一个新的(固定的)迁移并运行 Update-Database 时,即使是错误的迁移也会被应用。
我试图回滚到以前的迁移并删除迁移错误的文件。但是,当我尝试添加新迁移时,更新数据库时出现错误,因为迁移文件已损坏(更具体地说,第一行代码将表 A 重命名为 B 并且是下一行,EF 正在尝试更新表名称 A - 可能是一些 EF 错误)。
是否有一些我可以运行的查询,它会告诉 EF 类似“忘记上次迁移,就像它从未存在过一样,这很糟糕”?像移除迁移这样的东西。
Edit1 我找到了适合我的解决方案。将模型更改为良好状态并运行 Add-Migration TheBadMigration -Force
。这将重新构建最后一个未应用的迁移。
无论如何,这仍然不能完全回答原来的问题。如果我将 UpdateDatabase 迁移到错误的迁移,我没有找到如何回滚和创建新迁移的好方法,不包括错误的迁移。
谢谢
您有 2 个选项:
您可以从错误的迁移中取出 Down 并将其放入新的迁移中(您还需要对模型进行后续更改)。这有效地升级到更好的版本。我在已经进入多个环境的东西上使用这个选项。
另一种选择是针对您部署的数据库实际运行 Update-Database –TargetMigration: TheLastGoodMigration,然后从您的解决方案中删除迁移。这有点像 hulk 粉碎替代方案,需要针对使用错误版本部署的任何数据库执行此操作。注意:要重新构建迁移,您可以使用 Add-Migration [existingname] -Force。但是,这将覆盖您现有的迁移,因此请务必仅在您已从数据库中删除现有迁移时执行此操作。这与删除现有迁移文件并运行 add-migration 的作用相同,我在开发时使用此选项。
正如问题所示,这适用于尚未发布的开发类型环境中的迁移。
这个问题可以通过以下步骤解决:
将您的数据库恢复到上次良好的迁移。从您的 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
add-migration "new migration"
、update-database
dotnet tool install --global dotnet-ef
安装 dotnet ef
(EF Core 3.x) 后,我能够使用 dotnet-ef migrations list --project your-project-name
列出迁移。
对于那些将 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
你也可以使用
Remove-Migration -Force
这将恢复并删除上次应用的迁移
我将 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.
这让我的角色回到了我的数据库按预期工作的阶段,并从头开始。
Remove-Migration
和 remove
命令。但如果您仍在使用 EF6,则 Remove-Migration
和 remove
命令不可用。
remove
remove
,那么您必须使用 dotnet CLI。 Remove-Migration
命令用于 Visual Studios IDE 的包管理控制台 (PMC)。
首先,通过以下命令更新您的最后一次完美迁移:
Update-Database –TargetMigration
例子:
Update-Database -20180906131107_xxxx_xxxx
然后手动删除未使用的迁移。
Update-Database 20180906131107_xxxx_xxxx
(无连字符)对我有用。没有任何版本的 TargetMigration
作为开关起作用。这些命令似乎是一个移动的目标(即在每个版本中更改它们)?
从 .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
即使手动删除了最后一个迁移文件夹,它也会清理混乱并让您回到需要的位置。
对于 EF 6,如果您在开发中大量重新搭建脚手架,那么这里是单线。只需更新变量,然后继续使用包管理器控制台中的向上箭头来冲洗并重复。
$lastGoodTarget = "OldTargetName"; $newTarget = "NewTargetName"; Update-Database -TargetMigration "$lastGoodTarget" -Verbose; Add-Migration "$newTarget" -Verbose -Force
你问为什么这有必要?不确定这适用于哪个版本的 EF6,但如果您的新迁移目标已经应用,那么在 Add-Migration 中使用“-Force”重新构建脚手架实际上不会重新构建脚手架,而是制作一个新文件(这是一个很好的不过,因为你不想失去你的“失望”)。如有必要,上面的代码片段首先执行“向下”,然后 -Force 正常工作以重新搭建脚手架。
确保您在项目文件中没有错误,即使在您的迁移文件中,我在上一个迁移文件中也有错误并且不允许我将其删除。