Перехватить исключение дубликата ключа и продолжить вставку - PullRequest
0 голосов
/ 01 апреля 2020

У меня есть таблица в PostgreSQL с множеством записей и уникальным ключом

CREATE TABLE parcels
(
    Id SERIAL PRIMARY KEY NOT NULL,
    Number CITEXT NOT NULL,
    UserId INT REFERENCES Stations(Id) NOT NULL,
    TimeStampUtc TIMESTAMP WITHOUT TIME ZONE NOT NULL
);
CREATE UNIQUE INDEX ON parcels (Number, UserId, (TimeStampUtc::date));

, затем я импортирую данные из Excel и отображаю их в списке. В конце у меня что-то вроде

 await _dbContext.Parcels.AddRangeAsync(parcels);
 await _dbContext.SaveChangesAsync();

parcels содержит около 20000 записей и может содержать записи, которые нарушают уникальное ограничение. В таком случае мне нужно пропустить эти записи и продолжить вставку.

Теперь я получил ожидаемую ошибку

Microsoft.EntityFrameworkCore.DbUpdateException: ошибка при обновлении записей. Смотрите внутреннее исключение для деталей. ---> Npg sql .PostgresException: 23505: повторяющееся значение ключа нарушает уникальное ограничение "parcels_number_userid_timestamputc_idx"

Как игнорировать его и продолжать вставлять?

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

1 Ответ

0 голосов
/ 01 апреля 2020

Вы должны быть в состоянии сделать следующее:

  1. создать хранимую процедуру, которая получает посылки и выполняет вставку в паре с соединением в столбце с ограничением уникального ключа (= отфильтровать все, что уже имеет значение в условии where)
  2. вызывает хранимую процедуру из вашего кода и передает посылки

, если вам нужен искусственный идентификатор, есть два способы сделать это:

  • вернуть идентификатор из функции вставки (returning id), которую база данных, созданная для вас автоматически,
  • сгенерирует идентификатор на вашем клиенте (обычно работает только хорошо если у вас есть столбцы GUID)
...