【问题标题】:EF Core Bulk Extensions: Index was out of range on BulkInsertEF Core 批量扩展:BulkInsert 上的索引超出范围
【发布时间】:2020-05-22 01:19:53
【问题描述】:

我在使用 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 上下文, 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);

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

【问题讨论】:

  • parents.IndexOf(x) - parents.Count 你真的要分配负键值吗?因为,parents.Count 将大于 parents.IndexOf(x)

标签: c# entity-framework entity-framework-core bulkinsert


【解决方案1】:

由于在批量插入操作之前分配的 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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-28
    相关资源
    最近更新 更多