gpt4 book ai didi

entity-framework-migrations - EF Core 反复创建相同的迁移,更改标识列并且不做任何更改

转载 作者:行者123 更新时间:2023-12-04 10:52:21 35 4
gpt4 key购买 nike

最近,我向我的 EFCore2.2 DbContext(在 net47 项目中)添加了一个新数据实体,并多次尝试使用 CLI 工具生成迁移。在尝试更新数据库时,迁移失败,因为迁移尝试在不相关表中的标识列上更改列。我删除了迁移并删除了新实体,然后运行 ​​添加迁移 ,基本上是零代码更改。果然,在 Up & Down 方法中生成了相同的破坏性 AlterColumn 调用(似乎毫无意义)。这是迁移代码:

public partial class ServerConfig : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<long>(
name: "ID",
table: "ProfileParams",
nullable: false,
oldClrType: typeof(long))
.OldAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
}

protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<long>(
name: "ID",
table: "ProfileParams",
nullable: false,
oldClrType: typeof(long))
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
}
}

为了消除额外因素,我将代码恢复到最初添加此实体 (ProfileParams) 并创建迁移之后。我试过 添加迁移从那时起,实际上,我得到了与上面看到的相同的迁移代码(并且快照没有变化)。然后我将代码恢复到添加 ProfileParams 类之前,并生成实际创建该表的迁移。它与完整的 CREATE 相同,并且快照已适当更改。但是我马上跑了 添加迁移再次。瞧,我得到了与上面相同的额外“alter column”迁移,下一次迁移和下一次迁移都会有它。

因此,从本质上讲, future 的所有迁移似乎都会在 up/down 方法中添加相同的“alter column”。为什么?

为了解更多细节:
  • 其他各种表都有一个 ProfileParams 导航属性
    EFCore 被选为可空外键。
  • 快照的缩写位:

  • modelBuilder.Entity("ProfileParams", b =>
    {
    b.Property<long>("ID")
    .ValueGeneratedOnAdd();
    b.HasKey("ID");
    b.ToTable("ProfileParams");
    });

    modelBuilder.Entity("AssetUser", b =>
    {
    b.Property<string>("ID");
    b.Property<long?>("ParamsID");
    b.HasKey("ID");
    b.HasIndex("ParamsID");
    b.ToTable("AssetUsers");
    });

    modelBuilder.Entity("AssetUser", b =>
    {
    b.HasOne("ProfileParams", "Params")
    .WithMany()
    .HasForeignKey("ParamsID");
    });

    最佳答案

    问题是由于使用 uint对于主键,以及看起来像 EF Core 中的一个错误,试图默默地解决这个问题,然后以一种晦涩的方式默默地失败。

    在上面的例子中,尽管我没有显示原始实体类,但有问题的 ID 确实是类型 uint .其他问题的回答表明 EF Core 不支持无符号类型,但肯定会 假装 到,并造成这样一个困惑的局面!它没有在初始迁移中出现错误(它没有应用 SQL 自动标识所需的注释),而是继续创建它。

    如果实体类只有一个类型为 long 的 ID,这就是我们所期望的。 :

    migrationBuilder.CreateTable(
    name: "ProfileParams",
    columns: table => new
    {
    ID = table.Column<long>(nullable: false)
    /* But this part is missing when uint type is used! */
    .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
    },
    constraints: table =>
    {
    table.PrimaryKey("PK_ProfileParams", x => x.ID);
    });

    从那时起,永远向前,在所有 future 的迁移中,它将尝试通过更改带有注释的列来修复自己的遗漏。奇怪的是,即使它生成的“向下”函数也表明它已经有了注释,因为向上和向下是相同的!但是原始迁移和快照以及所有后续快照都无法捕获以下迁移尝试修复的内容。

    据推测,如果迁移被调整并且表实际上被删除并重新创建(不知道为什么 EF Core 认为它可以改变标识列!)那么生成的 SQL 表将具有自动标识 bigint键,但填充实际 uint 可能会出现问题来自该值的 ID 字段。

    简而言之,只需使用长键即可。哇。

    关于entity-framework-migrations - EF Core 反复创建相同的迁移,更改标识列并且不做任何更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59420256/

    35 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com