簡體   English   中英

實體框架代碼優先:遷移失敗,更新數據庫,強制不必要的(?)添加遷移

[英]Entity Framework code-first: migration fails with update-database, forces unneccessary(?) add-migration

我使用遷移(EF 5.0)和代碼優先有一個有趣的效果:

我創建了一些帶有 GUID 主鍵的模型。 (順便說一句:對我來說很重要,SQL Server 使用NEWSEQUENTIALID() ,這似乎是當前版本中的默認值)

在某些時候,我激活了遷移。 我在初始遷移中添加了一些代碼,根據需要,這主要是.Index()

當我刪除數據庫並調用 update-database 時,出現以下錯誤:

無法更新數據庫以匹配當前模型,因為存在未決更改且自動遷移已禁用。 將掛起的模型更改寫入基於代碼的遷移或啟用自動遷移。 將 DbMigrationsConfiguration.AutomaticMigrationsEnabled 設置為 true 以啟用自動遷移。 您可以使用 Add-Migration 命令將掛起的模型更改寫入基於代碼的遷移。

我嘗試了AutomaticMigrationsEnabled = true ,它無需更改或添加任何內容即可工作!

但由於我不想要AutomaticMigrationsEnabled ,我也嘗試再次刪除數據庫,調用update-database然后add-migration 我最終得到了一個似乎沒有改變任何東西的額外遷移(見下文)。 我還嘗試將這些行添加到初始遷移的底部 - 但這不會改變任何內容。

型號之一:

[Table(Speaker.TABLENAME)]
public class Speaker : BaseModel
{
    public const String TABLENAME = "Speaker";

    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    [Required]
    [MaxLength(50, ErrorMessage = "Name must be 50 characters or less")]
    public string Name { get; set; }
}

初始遷移代碼:

public partial class InitialCreate : DbMigration
{
    public override void Up()
    {
        // [...]
        CreateTable(
            "dbo.Speaker",
            c => new
                {
                    Id = c.Guid(nullable: false, identity: true),
                    Name = c.String(nullable: false, maxLength: 50),
                })
            .PrimaryKey(t => t.Id)
            .Index(t => t.Name, true, false);   // added manually: unique Name
        // [...]
    }
}

internal sealed class Configuration : DbMigrationsConfiguration<MyProject.Repositories.DBContext>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = false;
    }

    protected override void Seed(MyProject.Repositories.DBContext context)
    {
        // ...
    }
}

下面是由 add-migration 創建的代碼:它似乎沒有做任何新的事情——也許我遺漏了什么?

public partial class UnneccessaryMigration : DbMigration
{
    public override void Up()
    {
        // isn't this the exact same code from InitialMigrations?
        AlterColumn("dbo.Speaker", "Id", c => c.Guid(nullable: false, identity: true));
        // ...
    }

    public override void Down()
    {
        //...
        AlterColumn("dbo.Speaker", "Id", c => c.Guid(nullable: false));
    }
}

所以我很好奇:我做了什么使遷移迷失方向? 我該怎么做才能使其僅通過一次初始遷移工作?

解決方案:以下解決方法對我有用:

  1. 我刪除了數據庫和所有遷移,如下所述: https ://stackoverflow.com/a/11679386/3168401
  2. 已執行的 Enable-Migrations + Add-Migration Initial
  3. 將我手工制作的 .Index() 更改合並到文件中。 現在更新數據庫再次工作 - 刪除數據庫時也會重復。

我還嘗試再次刪除數據庫,稱為更新數據庫,然后添加遷移。 我結束了一個額外的遷移,它似乎沒有改變任何東西(見下文)

根據以上細節,我認為您已經先完成了最后一件事。 如果您在Add-migration之前運行Update database ,它不會使用您的遷移模式更新數據庫。 首先,您需要添加遷移,然后運行更新命令。

使用包管理器控制台按此順序嘗試它們。

PM> Enable-migrations //You don't need this as you have already done it
PM> Add-migration Give_it_a_name
PM> Update-database

實體框架在身份字段方面確實存在一些問題。

您不能在現有表上添加 GUID 標識

遷移:不檢測對 DatabaseGeneratedOption 的更改

逆向工程不會將具有默認 NEWSEQUENTIALID() 的 GUID 鍵標記為存儲生成的身份

這些都沒有准確描述您的問題,額外遷移中的 Down() 方法很有趣,因為當初始遷移中的 CREATE TABLE 似乎設置它時,它似乎試圖從列中刪除 IDENTITY!

此外,如果您使用Update-Database -ScriptUpdate-Database -Verbose查看從這些AlterColumn方法運行的 sql,您將看到 sql 在UpDown是相同的,實際上什么都不做。 IDENTITY 保持不變(對於當前版本 - EF 6.0.2 及以下) - 如我鏈接到的前 2 個問題中所述。

我認為您應該刪除額外遷移中的冗余代碼,並暫時使用空遷移。 您可以訂閱/投票支持要解決的問題。

參考:

更改 IDENTITY 選項確實很簡單

使用自定義遷移操作打開/關閉身份

試試這個:

PM> Enable-migrations -force
PM> Add-migration MigrationName
PM> Update-database -force

對我來說,我在 Visual Studio 2015 中解決了以下問題:從“視圖”菜單中單擊“其他 Windows”,然后單擊“包管理器控制台”,然后運行以下命令:

PM> enable-migrations

已在項目“mvcproject”中啟用遷移。 要覆蓋現有的遷移配置,請使用 -Force 參數。

PM> enable-migrations -Force

檢查上下文是否以現有數據庫為目標...為項目 mvcproject 啟用代碼優先遷移。

然后在遷移文件夾下添加遷移名稱,它會通過運行以下命令在解決方案資源管理器中添加您需要的類

PM>Add-migration AddColumnUser

最后更新數據庫

PM> update-database 

使用 VS2019 時,MVC5 - 在 Migrations 文件夾下查看文件 Configuration.cs 編輯:AutomaticMigrationsEnabled = true

    ——

回答您的一般問題

所以我很好奇:我做了什么使遷移迷失方向? 我該怎么做才能使其僅通過一次初始遷移工作?

在我合並了幾個分支並且遷移對數據庫的當前狀態感到困惑之后,我剛剛收到了與您相同的錯誤消息。 最糟糕的是,這只會發生在客戶端的服務器上,而不是我們的開發系統上。

在試圖弄清楚那里發生了什么時,我遇到了這個極好的微軟指南:

Microsoft 的團隊環境中的 Code First 遷移指南

雖然編寫該指南是為了解釋團隊中的遷移,但它也給出了我發現的關於遷移在內部如何工作的最佳解釋,這很可能會導致對您所看到的行為的解釋。 對於使用 EF6 或更低版本的任何人來說,花一個小時來閱讀所有這些內容是非常值得的。

對於在合並遷移后通過該錯誤消息提出此問題的任何人,使用數據庫的當前狀態生成空白遷移的技巧為我解決了問題,但請務必閱讀整個指南以了解該解決方案是否適用適合你的情況。

我遇到了這個問題,上面的建議沒有幫助。 我發現 add-migration 讀取當前狀態並創建當前模型的簽名。 您必須在修改之前修改您的模型。 所以順序是。

  1. 修改模型
  2. 運行添加遷移

我做了相反的事情並在修改我的模型(它是空的,所以我添加了新列)之前添加了遷移,然后運行了我的代碼。

希望這會有所幫助。

如果您首先根據現有數據庫將上下文模型設置為代碼,則必須進行設置遷移:

Add-Migration InitialCreate –IgnoreChanges
Update-database -force

然后更改您的上下文模型並設置:

Add-migration RemoveIspositive
Update-database -force

我知道這是一個非常古老的線程。 但是,想分享我如何在我的場景中遇到該消息,以防它可能對其他人有所幫助

  1. 我在本地機器上創建了一個Add-Migration <Migration_name> 還沒有運行update-database
  2. 同時,在父分支中有一系列提交,我必須向下合並。 合並也有一個遷移,當我修復沖突時,我最終有 2 個遷移添加到我的項目中,但不是通過update-database執行的。
  3. 現在我不在我的應用程序中使用enable-migrations -force 我更喜歡的方法是執行update-database -script命令來控制我需要的目標遷移。
  4. 因此,當我嘗試執行上述命令時,出現了相關錯誤。

我的解決方案是運行update-database -Script -TargetMigration <migration_name_from_merge>然后我的update-database -Script -TargetMigration <migration_name>生成了 2 個我能夠在本地數據庫上手動運行的腳本。

不用說,上面的經驗是在我的本地機器上。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM