EF Core Bulk Extensions: индекс был вне диапазона на BulkInsert - PullRequest
0 голосов
/ 06 февраля 2020

Я получаю следующую ошибку при использовании массовой вставки из расширений ядра EF:

Индекс был вне диапазона. Должен быть неотрицательным и меньше размера коллекции. (Параметр 'index') в System.Collections.Generi c .List 1.get_Item(Int32 index) at EFCore.BulkExtensions.TableInfo.UpdateEntitiesIdentity[T](IList 1 сущностей, IList 1 entitiesWithOutputIdentity) at EFCore.BulkExtensions.TableInfo.LoadOutputData[T](DbContext context, IList 1 сущностей) в EFCore.BulkExtensions.SqlBulkOperation.Merge [T] (контекст DbContext, IList 1 entities, TableInfo tableInfo, OperationType operationType, Action 1) progress) в EFCore.BulkExtensions.DbContextBulkExtensions.BulkInsert [T] (контекст DbContext, IList 1 entities, BulkConfig bulkConfig, Action 1 progress)
в MyProject.Data.Repository.Repository 1.CreateRange(List 1 сущностей)

У меня есть родительский объект и дочерний объект. Я пытаюсь сначала выполнить массовую вставку родителя, а затем назначить идентификаторы, сгенерированные для родителя, своим детям. Затем выполните массовую вставку потомков.

CreateRange метод:

public List<T> CreateRange(List<T> entities)
{
    var bulkConfig = new BulkConfig { PreserveInsertOrder = true, SetOutputIdentity = true };
    _dbContext.BulkInsert(entities, bulkConfig);
    return entities;
}

Код массовой вставки:

// Index parents. (Since PreserveInsertOrder = true is set.)
parents.ForEach(x => x.Id = parents.IndexOf(x) + 1);
_parentRepository.CreateRange(parents);

// parent-child relation mapping.
parents.ForEach(x => x.Children.ToList().ForEach(y => y.ParentId = x.Id));

var children = parents.SelectMany(x => x.Children).ToList();
// Index children. (Since PreserveInsertOrder = true is set.)
children.ForEach(x => x.Id = children.IndexOf(x) + 1);
_childRepository.CreateRange(children);

Не всегда возможно воспроизвести эту проблему. Я не могу определить условие для воспроизведения этой проблемы.

1 Ответ

0 голосов
/ 07 февраля 2020

Исключение происходит из-за того, что идентификаторы назначаются до того, как операция массовой вставки конфликтует с идентификаторами, уже существующими в базе данных. Решением является использование идентификаторов, которых нет в базе данных. Например, отрицательные числа. Это все еще может сохранить порядок вставки, поскольку важен относительный порядок между сущностями в списке, который будет вставлен.

Модифицированный код:

// Index parents with non-conflict keys. (Since PreserveInsertOrder = true is set.)
parents.ForEach(x => x.Id = parents.IndexOf(x) - parents.Count);
_parentRepository.CreateRange(parents);

// parent-child relation mapping.
parents.ForEach(x => x.Children.ToList().ForEach(y => y.ParentId = x.Id));

var children = parents.SelectMany(x => x.Children).ToList();
// Index children with non-conflict keys. (Since PreserveInsertOrder = true is set.)
children.ForEach(x => x.Id = children.IndexOf(x) - children.Count);
_childRepository.CreateRange(children);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...