Как устранить ошибку миграции EF Core с помощью HiLo?

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

  • .Сетевое ядро ​​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 присваивает странные 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 я нашел решение для странных идентификаторов. Я сделал имя 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();

Я не очень хорошо знаком с использованием PostgreSQL с EF, но что происходит вместо того, чтобы добавлять ForNpgsqlUseSequenceHiLo в широком смысле, вы добавляете его для каждой отдельной сущности? Кроме того, не уверен насчет этого вызова base.OnModelCreating(modelBuilder);. В документах не указано npgsql.org/efcore/…

jpgrassi 03.05.2019 11:20

Хм... Я никогда не думал об этом. Я постараюсь и дам вам знать :)

Morasiu 03.05.2019 11:21

Ошибка все еще возникает, файл миграции выглядит так же, все тесты пройдены и в основном все то же самое, что и при использовании modelBuilder.ForNpgsqlUseSequenceHiLo();. Также мне нужен base.OnModelCreating(modelBuilder); для идентификации

Morasiu 03.05.2019 11:30

Проблема миграции: что делается в Down миграции? EntityFrameworkHiLoSequence тоже выпал? Теперь генерация идентичности, я понятия не имею.. но что вы имеете в виду, что вам это нужно для идентичности? Под идентичностью вы имеете в виду колонку идентичности? Если да, то зачем вам последовательность HiLo? Немного запутался сейчас.

jpgrassi 03.05.2019 11:33

@jpgrassi Во-первых, я обновил свой вопрос. Во-вторых, под идентификацией я подразумеваю Удостоверение Майкрософт. Извините за умственный ярлык В-третьих, спасибо за вашу помощь. Вы частично решили мою проблему.

Morasiu 03.05.2019 11:45

Вместо того, чтобы запускать миграцию автоматически, попробуйте сгенерировать для вас скрипт SQL: запустите dotnet ef migrations script <hilo sequence migration> <older migration> -o migration.sql и посмотрите, что сгенерировал SQL. Очевидно, есть какая-то проблема с тем, что последовательность не сбрасывается. Может быть, это не в той же схеме, что и база данных?

jpgrassi 03.05.2019 11:54

Давайте продолжить обсуждение в чате.

Morasiu 03.05.2019 11:58

Я добавил ответ, чтобы другие тоже могли извлечь выгоду. Взгляните на него, а также на образец приложения, который я создал.

jpgrassi 03.05.2019 22:12
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
8
1 973
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

По поводу "странного" сгенерированного идентификатора. Вам нужно создать одну последовательность для каждого объекта, чтобы они не «делили» идентификаторы. Подробнее о документации провайдера: Генерация автоинкремента HiLo

Переопределите 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, в котором используется EF Core с PostegreSQL, и я смог нормально удалить/создать базу данных.

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

Другие вопросы по теме