Как устранить ошибку миграции EF Core с помощью HiLo? - PullRequest
0 голосов
/ 03 мая 2019

Немного фона. Я использую:

  • .Net Core 2.2.3
  • Postgres как моя база данных
  • Npgsql.EntityFramworkCore.PostgreSQL 2,20
  • EntityFramwork как 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 назначает странные идентификаторы (но все еще уникальные). Как странно? Позволь мне объяснить. Например:

У меня есть таблицы

  • Заказы
  • ТоварыЗаказ
  • Роли (полностью не связанные с предыдущим).

И я делаю простое начальное число для базы данных, которая присваивает идентификаторы следующим образом:

Заказы:

  • 1 MyOrder1

OrderItem:

  • 2 MyOrderItem1
  • 3 MyOrderItem2
  • 4 MyOrderItem3

Роль:

  • 5 MyRole1
  • 6 MyRole2

Похоже, он разделил HiLo для всех таблиц. Я думал, что это HiLo за столом.

Также я получаю ошибку, когда использую чистую новую миграцию и делаю:

  • dotnet ef database drop && dotnet ef database update

У меня ошибка (перевод на английский с польского):

42P07: relation "EntityFrameworkHiLoSequence" already exist

@ UPDATE

Благодаря @jpgrassi я нашел решение для странных идентификаторов. Я сделал название 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");

Мой вопрос: Почему эта ошибка выдается при чистой миграции и как от нее избавиться?

1 Ответ

1 голос
/ 03 мая 2019

Несмотря на то, что ОП отредактировал сообщение и в значительной степени решил проблему с моей помощью, я опубликую фактический ответ, чтобы другие, сталкивающиеся с той же самой «проблемой», могли извлечь выгоду.

Относительно «странного» идентификаторагенерироваться.Вам нужно создать одну последовательность для каждой сущности, чтобы они не «делили» идентификаторы.Подробнее о документации поставщика: 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 Я не смог ее воспроизвести.Я создал пример ASP.NET Core App, который использует EF Core с PostegreSQL, и я смог нормально удалить / создать базу данных.

Я перенес приложение в свою учетную запись GitHub, чтобы вы могли клонировать его и попробоватьсебя: efcore-postgres-hilo-sequence

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...