EF Core 批量扩展:索引超出了大容量插入的范围



我在使用 EF 核心批量扩展的批量插入时收到以下错误:

指数超出范围。必须为非负数且小于 集合。(参数"索引"(在 System.Collections.Generic.List1.get_Item(Int32 index) at EFCore.BulkExtensions.TableInfo.UpdateEntitiesIdentity[T](IList1 实体,IList1 entitiesWithOutputIdentity) at EFCore.BulkExtensions.TableInfo.LoadOutputData[T](DbContext context, IList1 个实体(在 EFCore.BulkExtensions.SqlBulkOperation.Merge[T](DbContext context, IList1 entities, TableInfo tableInfo, OperationType operationType, Action1 进度( 在 EFCore.BulkExtensions.DbContextBulkExtensions.BulkInsert[T](DbContext 上下文,IList1 entities, BulkConfig bulkConfig, Action1 进度(在 MyProject.Data.Repository.Repository1.CreateRange(List1 个实体(

我有一个父实体和子实体。我正在尝试做的是,首先批量插入父级,然后将为父级生成的 ID 分配给他们的子级。然后批量插入子项。

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);

并非总是能够重现此问题。我无法确定重现此问题的条件。

发生异常的原因是,在批量插入操作与数据库中已存在的 ID 冲突之前分配了 Id。解决方案是使用不在数据库中的 ID。例如,负数。这仍然可以保留插入顺序,因为重要的是要插入的列表中实体之间的相对顺序。

修改后的代码:

// 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);

最新更新