實體框架程式碼優先:如何手動更新數據庫?
我建構了一個小的 WPF 展示應用程序,它使用 EF Code-First 將其數據保存在 SQL CE 4.0 DB 中。除非我從模型對像中刪除屬性,否則它工作正常。例如,如果我從此類中刪除“HosteBy”……
public class Dinner { public int DinnerID { get; set; } public string Title { get; set; } public DateTime EventDate { get; set; } public string Address { get; set; } public string HostedBy { get; set; } public virtual ICollection<RSVP> RSVPs { get; set; } }…它拋出這個異常:
自數據庫創建以來,支持“NerdDinners”上下文的模型已更改。手動刪除/更新數據庫,或使用 IDatabaseInitializer 實例呼叫 Database.SetInitializer。例如,DropCreateDatabaseIfModelChanges 策略將自動刪除並重新創建數據庫,並可選擇使用新數據為其播種。
即使從數據庫中手動刪除了“HosteBy”欄位,該錯誤仍然存在。我在這裡想念什麼?我必須刪除/截斷數據庫還是有其他解決方案?
在您更改 Code First 模型的第一個場景中,在您手動修改數據庫之前,答案是打開 (Nuget) 包管理器控制台並鍵入:
update-database -verbose除了 - 因為在這種情況下您正在刪除一個列,這將報告它即將刪除某些內容,並且如果您沒有明確表示可以,它不會刪除任何內容。所以你輸入:
update-database -f -verbose現在這將刪除您在模型中擁有的列。
-verbose說要向你展示它執行的 SQL。如果您害怕讓它刪除一些東西,而是在執行之前檢查 SQL,請使用:更新數據庫 -f -腳本
這會將 SQL 轉儲到您可以查看的腳本中,然後自己手動執行。它包括一條 SQL 行,用於更新 EF Code First 自己對數據庫的理解。
在您繼續手動刪除數據庫中的列的情況下,您現在手頭有一個更複雜的場景。實體框架創建的數據庫中有一個表,
EdmMetadata在舊版本和_MigrationHistory新版本中呼叫。該表包含整個數據庫的散列,該散列現在與數據庫本身不匹配。由於不匹配,執行遷移(update-database)現在將一遍又一遍地中斷,直到您解決它。雜湊對人類不友好,不會幫助你。您可以通過多種方式解決它:
- 您可以使用
add-migration <name>. 在這種情況下,我可以用add-migration DeletePurchaseColumn列的名稱或任何名稱來命名它。在生成的 C# Schema Migrations 程式碼中,在Up()方法中,註釋掉處理您已刪除的列的 DeleteColumn 行。下次執行update-database時,程式碼將:查看雜湊,查看手動遷移列表,查看是否有比數據庫狀態更新的手動遷移,執行自動遷移,直至生成儲存在手動遷移 C# 程式碼中的雜湊,執行手動遷移,然後更新數據庫中的雜湊。如果它沒有得到任何 SQL 錯誤,無論如何。這是我解決此問題的最常用方法。- 您可以執行手動 SQL 以通過檢查您之前擁有的內容和您的數據庫目前的樣子,將數據庫返回到 Entity Framework 期望的方式(手動修改之前的方式,使其與雜湊一致)。在這種情況下,您需要重新添加該列,這樣 EF 就可以刪除它。
- 如果您與雜湊值和數據庫的實際外觀相距甚遠,則應考慮通過清除程式碼中的任何手動遷移和數據庫中的 EF 版本歷史記錄表來重新開始遷移,然後從
enable-migrations.麻煩
您仍然可能會遇到麻煩,例如,如果您在 db 模式中有一個 EF 難以辨識、表示或匹配的安排。自引用表可能會導致麻煩,任何關於主鍵的有趣的事情都會引起麻煩 - 例如,在表之間共享一個鍵需要仔細的 C# 工作以將程式碼與架構匹配。
最簡單的方法是備份數據庫,嘗試一系列
add-migration手動遷移,然後整理結果。例如,如果數據庫中有一個列瘋狂地竊聽 EF,例如數據類型沒有得到很好的支持或複雜的密鑰共享安排,但這並不重要,因為你不會’無論如何都不要訪問它,您可以將它放入雜湊中,然後通過生成手動遷移來停止考慮它add-migration,註釋掉該列的 AddColumn 程式碼(或重命名或更新),然後繼續。手動遷移中生成的雜湊將擷取 EF 對該列的足夠好印象,您將能夠繼續您的工作。但是,如果您確實從程式碼中訪問過該列,那麼 EF 很有可能會爆炸。因此,您應該在帶有該警告的列中添加註釋。如果以上都不起作用,那麼您現在處於 Entity Framework Code First 中最醜陋的部分。您需要消除雜湊表並將數據庫反向工程為程式碼文件。
第二步(將數據庫逆向工程為程式碼)的好消息是,Microsoft 已經發布了一個測試版工具,可以為您執行此操作。
您可以跳過那裡的許多第一步,因為他們只是設置數據庫並添加一些廢話,以便他們可以展示您需要做什麼:對數據庫進行逆向工程。