0

我有我的初始遷移文件,其中包含所有實體表,並更新數據庫幷包含所有表。 現在我想改變一個表並將聚集索引從主鍵更改爲另一個索引。代碼修改如下所示。 我在這裏做了兩個小的改變,爲主鍵設置爲假,另一個索引爲真。不知道這是否會工作,因爲現在我試圖更新數據庫時出現錯誤。更改遷移文件的表後,如何更新數據庫?

CreateTable(
      "dbo.YogaSpaceEvents", 
      c => new 
       { 
        YogaSpaceEventId = c.Int(nullable: false, identity: true), 
        Title = c.String(), 
        DateTimeScheduled = c.DateTime(nullable: false), 
        AppointmentLength = c.Int(nullable: false), 
        StatusEnum = c.Int(nullable: false), 
        YogaSpaceRefId = c.Int(nullable: false), 
       }) 
      .PrimaryKey(t => t.YogaSpaceEventId, clustered: false) 
      .ForeignKey("dbo.YogaSpaces", t => t.YogaSpaceRefId, cascadeDelete: true) 
      .Index(t => t.DateTimeScheduled, clustered: true) 
      .Index(t => t.YogaSpaceRefId); 

如果我運行update-database,我得到一個錯誤說「實體'blahblah'已經存在於數據庫中」。它來自遷移文件中的第一個「CrateTable」語句。用遷移文件中的更改更新數據庫的步驟是什麼?我是否需要創建另一個遷移文件,只進行更改?

回答

0

您高估了遷移機制。它的目的是管理連續遷移之間的數據庫轉換,但在遷移代碼中識別您的更改並不夠聰明。通常要更改數據庫結構,您必須使用代碼更改表,列,索引等來生成新遷移以匹配新結構。使用IndexAttribute(版本6.1),您可以將DateTimeScheduled上的索引定義爲集羣,並且EF將自動識別該模型已更改,以及何時使用添加遷移,它將生成遷移,以便爲您更改YogaSpaceEvents。

如果你堅持,你不希望有一個單獨的遷移,但這些變化應包括在當前的你有2種選擇:

  1. 遷移數據庫之前的遷移,使用「添加遷移-Force「重新生成當前遷移以匹配您的更改,然後將遷移應用到您的數據庫
  2. 使用」add-migration「添加新遷移,將更改應用到db。然後將您的數據庫遷移到最新狀態。之後,刪除新添加的遷移文件,並在某些測試數據庫上應用「添加遷移-Force」重新生成初始遷移,以便將其更改爲模型。最後要做的是刪除與刪除的遷移對應的數據庫__MigrationsHistory表中的行,並將與初始遷移相對應的thr行的「Model」字段值更新爲與刪除的遷移相對應的行中的「Model」字段的值。

在你的情況下,可能1)選項將不起作用,因爲你正在改變你的第一次遷移,所以恢復它會導致刪除所有數據庫結構和所有db數據。但是,如果你的數據庫不包含任何重要的數據,這是更簡單的方法。如果你想保存數據並且只有1次遷移,你必須使用路徑2)。

+0

嗨。也許我可以重新修改我的問題 - 如何修改遷移文件中的表格?我可以說「添加遷移ChangeIndex」並創建一個新文件。在該文件中,我想更改一些表索引(例如,將主鍵上的集羣刪除到另一個索引),然後更新數據庫。 – user1186050 2015-04-04 21:38:19

+1

據我所知,表上的聚集索引可能只有在創建時纔會設置。 EF遷移引擎不足以認識到這一點。所以在你的情況下,你將被強制刪除YogaSpaceEvents表(指令DropTable),並通過CreateTable指令提供的方式再次創建它。當然,在丟棄之前,您還需要刪除引用您的表的任何外鍵關係。如果你想從YogaSpaceEvents保存你的數據,那麼不要使用RenameTable來更改名稱,然後創建新表,使用Sql函數複製數據並刪除舊錶。 – mr100 2015-04-05 06:26:53

0

您無法編輯現有遷移並使其適用,而無需更新到該遷移,然後重新更新爲最新。這樣,您將運行所有Down()腳本,這會刪除表格。

或者,您構建新的遷移並明確執行Up()中所需的操作,並在Down()中將其撤銷。

相關問題