2014-03-27 56 views
93

我正在使用EF 6.0在C#中的項目中進行手動遷移和更新。我對數據庫有大約5次遷移,但是我意識到最後一次遷移很糟糕,我不想要它。我知道我可以回滾到先前的遷移,但是當我添加新的(固定)遷移並運行Update-Database時,即使是錯誤遷移也會應用。實體框架回滾並刪除錯誤的遷移

我試圖回滾到以前的遷移並刪除具有錯誤遷移的文件。但是,當我嘗試添加新的遷移時,在更新數據庫時出現錯誤,因爲遷移文件已損壞(更具體地說,第一行代碼將表A重命名爲B並且是下一行,EF正試圖用名字A - 也許這是一些EF錯誤)。

有一些查詢我可以運行,這將告訴EF像「忘記過去的遷移就像從來沒有存在過,這是不好的」?像刪除遷移。

EDIT1 我找到解決方案適合我。將模型更改爲良好狀態並運行Add-Migration TheBadMigration -Force。這將重新支持最後一次,而不是應用的遷移。

無論如何,這還不完全回答原來的問題。如果我將UpdateDatabase轉換爲錯誤遷移,我沒有找到如何回滾並創建新遷移的好方法,不包括壞的遷移。

感謝

回答

110

你有2種選擇:

  • 您可以從壞的遷移下來並把它放在一個新的遷移(你還需要對模型中的後續變化)。這實際上是一個更好的版本。

    我用的東西,去了多個環境這個選項。

  • 另一種選擇是實際運行Update-Database –TargetMigration: TheLastGoodMigration針對您部署的數據庫,然後從您的解決方案中刪除遷移。這有點像綠巨人的替代品,並且要求針對任何使用不良版本部署的數據庫執行此操作。

    注意:要重新進行遷移,您可以使用Add-Migration [existingname] -Force。但是,這會覆蓋您現有的遷移,因此只有在您從數據庫中刪除了現有遷移的情況下才能執行此操作。這與刪除現有遷移文件並運行同樣的事情add-migration

    我在開發時使用此選項。

+1

綠巨人粉碎選項不起作用。我還沒有將錯誤的遷移應用到數據庫。我試過了,但它不起作用,因爲我在原始問題中指定了表名。我不喜歡第一個選項,因爲它看起來像我將不得不更改遷移代碼。如果我做得不好,我可以把它打破。 –

+4

如果您尚未應用錯誤遷移,則無法阻止您刪除它並重新進行腳本遷移或更正已損壞的遷移。 –

+3

「綠巨人粉碎」就是答案,它在開發時適用於我,並且我想爲我錯過的遷移添加一些東西。我認爲它不適用於Martin的原因是無關的(或者可能與手動更改數據庫模式有關) – rethenhouser2

64

作爲問題表明這適用於在開發型環境遷移還沒有被釋放。

此問題可以分兩步解決,第一步是將數據庫恢復到上次良好遷移,然後從您的Entity Framework項目中刪除錯誤遷移。

第1步:恢復到以前的遷移

要還原數據庫架構到以前的點使用:

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

指定的最後一個良好的遷移。如果您尚未應用遷移,則可以跳過此部分。

使用Get-Migrations命令獲取已應用於數據庫的遷移名稱列表。

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>" 

在指定的所有遷移之後應用的所有遷移將按照最先應用的最新遷移的順序進行降級。

步驟2:從項目

刪除遷移現在,您可以刪除您EF項目「遷移」文件夾中的不良遷移。

26

對於使用EF核心與ASP.NET核心V1.0.0那些我有一個類似的問題,用下面的命令來糾正它(@ DavidSopko的帖子我指出了正確的方向,但在細節上略有不同對於EF核心)

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

例如,在我目前的發展命令成爲

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

的刪除遷移將刪除上次遷移喲你應用。如果你有一個更復雜的情況下需要移除多個遷移(我只有2個,最初和最後一個),我建議你測試一個虛擬項目中的步驟。

EF Core(v1.0.0)目前似乎沒有Get-Migrations命令,因此您必須查看您的migrations文件夾並熟悉所做的操作。然而,有一個很好的幫助命令:

PM> get-help entityframework 

在VS2015的SQL Server對象資源管理器刷新dastabase,我所有的數據被保留下來,而且我想恢復已經走了:)

起初我試圖遷移刪除遷移本身並發現錯誤命令令人困惑:

System.InvalidOperationException:遷移'...'已應用於數據庫的 。取消應用並重試。如果遷移 已應用於其他數據庫,請考慮使用新的遷移恢復其更改 。

已經有改善這一措詞的建議,但我想的錯誤說這樣的事情:

運行update-數據庫(最後一個良好的遷移名)恢復數據庫架構回到那個狀態。此命令將 未應用遷移指定爲 更新數據庫後發生的所有遷移。然後,您可以運行刪除遷移(遷移名稱以去除)從EF核心help命令

輸出如下:

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 
0

對於EF 6這裏是一個一行,如果你重新腳手架很多正在開發中。只需更新變量,然後繼續使用包管理器控制檯中的向上箭頭進行清洗並重復。

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

爲什麼您需要這樣做?不知道哪個版本的EF6適用,但是如果你已經應用了新的遷移目標,那麼在Add-Migration中使用'-Force'重新腳手架實際上不會重新腳手架,而是創建一個新文件(這是一個很好的但是因爲你不想失去你的'羽絨')。如果需要的話,上面的代碼片段首先執行「下」操作,然後--Force正常工作以重新腳手架。