繁体   English   中英

如何使用 HiLo 解决 EF Core 迁移错误?

[英]How to resolve EF Core migration error with HiLo?

一点背景。 我正在使用:

  • .Net 核心 2.2.3
  • Postgres 作为我的数据库
  • Npgsql.EntityFramworkCore.PostgreSQL 2.20
  • 实体框架作为 ORM

我在上下文中使用了那个简单的 HiLo 序列声明。

protected override void OnModelCreating(ModelBuilder modelBuilder) {
    base.OnModelCreating(modelBuilder);
    modelBuilder.ForNpgsqlUseSequenceHiLo();
}

这将创建我的迁移文件,如下所示:

protected override void Up(MigrationBuilder migrationBuilder)
{
    migrationBuilder.CreateSequence(
        name: "EntityFrameworkHiLoSequence",
        incrementBy: 10);

    migrationBuilder.CreateTable(
        name: "AspNetRoles",
        columns: table => new
        {
            Id = table.Column<int>(nullable: false)
                .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SequenceHiLo),
            Name = table.Column<string>(maxLength: 256, nullable: true),
            NormalizedName = table.Column<string>(maxLength: 256, nullable: true),
            ConcurrencyStamp = table.Column<string>(nullable: true)
        },
        constraints: table =>
        {
            table.PrimaryKey("PK_AspNetRoles", x => x.Id);
        });
    // other tables code goes here... All key has
    // .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SequenceHiLo)
}

一切正常,但 HiLo 分配了奇怪的 ID(但仍然是唯一的)。 多奇怪? 让我解释。 例如:

我有桌子

  • 订单
  • 订单项
  • 角色(与之前完全无关)。

我对数据库做了一个简单的种子,分配 ID 如下:

订单:

  • 1 我的订单 1

订单项:

  • 2 我的订单项 1
  • 3 我的订单项 2
  • 4 我的订单项 3

角色:

  • 5 我的角色1
  • 6 我的角色 2

所以看起来它已经为所有表共享了 HiLo。 我认为每桌都是 HiLo。

当我使用全新的迁移并执行以下操作时,我也会出错:

  • dotnet ef database drop && dotnet ef database update

我有错误(从波兰语翻译成英语):

42P07: relation "EntityFrameworkHiLoSequence" already exist

@更新

感谢@jpgrassi,我找到了奇怪 ID 的解决方案。 我为每个模型都命名了 HiLo。 它看起来像这样:

protected override void OnModelCreating(ModelBuilder modelBuilder) {
    base.OnModelCreating(modelBuilder);

    modelBuilder.Entity<OrderItem>()
        .Property(b => b.Id)
        .ForNpgsqlUseSequenceHiLo("OrderItemsHiLo");

    modelBuilder.Entity<Order>()
        .Property(b => b.Id)
        .ForNpgsqlUseSequenceHiLo("OrdersHiLo");
    // More sequences goes below...
}

现在这一切听起来合乎逻辑。 但是......我有新的错误:

42P07: relation "OrderItemsHiLo" already exist

我的Up部分:

protected override void Up(MigrationBuilder migrationBuilder)
{
    migrationBuilder.CreateSequence(
        name: "OrderItemsHiLo",
        incrementBy: 10);
    // more code...
}

在我的Down迁移部分中,我有:

migrationBuilder.DropSequence(name: "OrderItemsHiLo");

我的问题是:为什么在干净迁移时会抛出这个错误以及如何摆脱它?

@更新

我刚刚删除了那条线,它解决了我的第二个问题。 愚蠢的我...

_context.Database.EnsureCreatedAsync();

尽管 OP 编辑​​了帖子并在我的帮助下几乎解决了问题,但我会发布一个实际答案,以便其他遇到相同“问题”的人可以受益。

关于生成的“奇怪”ID。 您需要为每个实体创建一个序列,因此它们不会“共享”ID。 有关提供程序文档的更多信息: HiLo Autoincrement Generation

重写OnModelCreating在你DbContext类,并添加这样的:

 modelBuilder.Entity<OrderItem>()
        .Property(b => b.Id)
        .ForNpgsqlUseSequenceHiLo($"Sequence-{nameof(OrderItem)}");

// same for others you want a sequence

重新添加迁移,你应该有这样的东西:

 migrationBuilder.CreateSequence(
                name: "Sequence-OrderItem",
                incrementBy: 10);

// Order entity code ommited
Id = table.Column<int>(nullable: false)
                        .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SequenceHiLo)

现在关于您的“第二个”问题,关于在运行dotnet ef database drop后无法重新创建dotnet ef database drop我无法重现它。 我创建了一个示例 ASP.NET Core 应用程序,它使用 EF Core 和 PostegreSQL,我能够正常删除/创建数据库。

我把这个应用推送到我的 GitHub 账户,所以你可以克隆它并自己尝试: efcore-postgres-hilo-sequence

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM