Игнорировать повторяющиеся записи и фиксировать успешные записи в DbContext.SaveChanges () в EF Core - PullRequest
0 голосов
/ 27 мая 2019

У меня есть ASP .Net Core 2.2 Web API.В одном из моих действий контроллера я добавляю несколько строк в таблицу базы данных MySQL (я использую Pomelo).

Так, например:

_dbContext.AddRange(entities);
_dbContext.SaveChanges();

Сущности, которые я 'При добавлении у меня есть два первичных ключа (составной первичный ключ), и ключи уже заполняются в коллекции сущностей, когда я добавляю их в DbContext (т. е. я сам устанавливаю ключи - не существует «автоинкремента» или чего-либо подобного в базе данных).генерирует ключи)

Если какая-либо сущность, которую я добавляю, уже существует в базе данных с точки зрения дублирования первичного ключа, то, очевидно, SaveChanges () генерирует исключение, и вся транзакция откатывается.

Есть ли способ заставить EF Core игнорировать ошибочные объекты?т.е. игнорировать сущности, которые уже существовали в базе данных, и фиксировать сущности, которые успешно (то есть, которые не существовали в базе данных)?Вместо текущего поведения, которое вызывает исключение и откатывает всю транзакцию?

Спасибо

1 Ответ

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

Похоже, у вас проблемы с бизнесом. Во-первых, вам нужно решить, что произойдет, если у вас уже есть объект с таким же идентификатором, и кто-то пытается вставить новый объект (новую информацию) с тем же идентификатором.

Похоже, вы уже решили: вы хотите отказаться от действия.

Это как-то необычно, потому что если вы получаете какие-то новые данные от клиентов этого API о сущности, которая уже существовала в вашей базе данных -> это больше похоже на обновление.

Существуют некоторые библиотеки, которые могут делать нечто подобное: https://github.com/borisdj/EFCore.BulkExtensions (который в настоящее время работает только с MsSQL)

Используя эту библиотеку (которая известна и уже упоминалась Microsoft как EF Core Tool: https://docs.microsoft.com/en-us/ef/core/extensions/), у вас есть возможность:

  • Вставить или обновить все данные (все столбцы), если вы найдете объект с таким же идентификатором (Upsert):

    context.BulkInsertOrUpdateAsync(entitiesList);

  • Синхронизируйте сущности из вашей базы данных с любыми сущностями, которые вы получаете от клиентов:

    context.BulkInsertOrUpdateOrDeleteAsync(entitiesList);

Скорее всего, вы не найдете что-то уже реализованное для вашего случая, но вы можете настроить эту библиотеку с помощью:

BulkInsertOrDropAsync 

Что будет делать что-то вроде:

WHEN MATCHED THEN UPDATE SET A.ID=A.ID --The ID's are already the same so nothing will happen
WHEN NOT MATCHED THEN INSERT(A.ID,A.NAME,A.CODE,A.DESCRIPTION) 

Что на самом деле не DROP, но оно не затронет ваши данные.

...