实体框架代码优先:迁移失败,更新数据库,强制不必要的(?)添加迁移

问题描述 投票:64回答:4

我使用迁移(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. 我删除了数据库和所有迁移,如下所述:qazxsw poi
  2. 执行启用 - 迁移+添加迁移初始
  3. 合并我的手工.Index()更改到文件中。现在,Update-Database再次运行 - 在删除数据库时也会重复运行。
entity-framework ef-migrations
4个回答
99
投票

我还尝试再次删除数据库,称为update-database,然后添加迁移。我最终得到了一个似乎没有改变任何东西的额外迁移(见下文)

基于以上细节,我认为你先做了最后一件事。如果在https://stackoverflow.com/a/11679386/3168401之前运行Update database,它将不会使用您的迁移模式更新数据库。首先,您需要添加迁移,然后运行update命令。

使用包管理器控制台按此顺序尝试它们。

Add-migration

9
投票

实体框架确实在身份字段方面存在一些问题。

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

You can't add GUID identity on existing table

Migrations: does not detect changes to DatabaseGeneratedOption

这些都没有完全描述您的问题,并且额外迁移中的Down()方法很有趣,因为当初始迁移中的CREATE TABLE似乎设置它时,它似乎试图从列中删除IDENTITY!

此外,如果您使用Reverse engineering does not mark GUID keys with default NEWSEQUENTIALID() as store generated identitiesUpdate-Database -Script查看从这些Update-Database -Verbose方法运行的sql,您将看到qql在AlterColumnUp中是相同的,并且实际上什么都不做。 IDENTITY保持不变(对于当前版本 - EF 6.0.2及更低版本) - 如我链接的前两个问题中所述。

我认为您应该删除额外迁移中的冗余代码,并暂时使用空迁移。您可以订阅/投票支持要解决的问题。

参考文献:

Down

Change IDENTITY option does diddly squat



1
投票

对我来说,我解决了以下问题在Visual Studio 2015中:从“查看”菜单中单击“其他Windows”,然后单击“程序包管理器控制台”,然后运行以下命令:

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

已在项目“mvcproject”中启用了迁移。要覆盖现有迁移配置,请使用-Force参数。

PM> enable-migrations

检查上下文是否以现有数据库为目标...为项目mvcproject启用了代码优先迁移。

然后在迁移文件夹下添加迁移名称,它将通过运行以下命令在解决方案资源管理器中添加所需的类

PM> enable-migrations -Force

最后更新数据库

PM>Add-migration AddColumnUser

0
投票

使用VS2019时,MVC5 - 在Migrations文件夹下查看文件Configuration.cs编辑:AutomaticMigrationsEnabled = true

    -
© www.soinside.com 2019 - 2024. All rights reserved.