具有一对一关系的 EF Core 批量插入

Posted

技术标签:

【中文标题】具有一对一关系的 EF Core 批量插入【英文标题】:EFCore BulkInsert with one to one relationship 【发布时间】:2020-08-07 10:04:47 【问题描述】:

我正在尝试在 .NET Core 2.1 中使用 EFCore.BulkExtensions 中的 bulkinsert 与一对一关系。我有 2 个数据库实体

public partial class Entity1

    public int ID  get; set; 
    public virtual Entity2 Entity2Obj  get; set; 


public partial class Entity2 

    public int ID  get; set; 
    public int Entity1_ID get; set; 
    public virtual Entity1 Entity1Obj  get; set; 

然后我插入一个 Entity1 项目列表

 _context.BulkInsert(Entity1ItemsList);

这仅适用于在我的数据库中插入 Entity1 对象。未插入关联的 Entity2 项。有没有办法做到这一点?

导航属性在 Scaffold-DbContext 期间自动创建(数据库优先)

entity.HasOne(d => d.Entity1 )
    .WithOne(p => p.Entity2)
    .HasForeignKey<Entity2>(d => d.Entity1_ID)
    .OnDelete(DeleteBehavior.ClientSetNull)
    .HasConstraintName("FK_Entity1_Entity2");

【问题讨论】:

您是否为Entity2Obj 的每个Entity1ItemsList 项目设置了数据? 这里是经验法则:确保在 Entity1Entity2 之间正确配置了您的关系...这可能意味着使用 FluentAPi 配置它们,因为您具有导航属性...其次确保Entity1ItemsList 中的所有对象都将数据传递给 Entity2Obj 是的,Entity1ItemsList 中的每个 Entity2Obj 项目都有数据。这些关系是在 Scaffold-DbContext 期间自动设置的,因为它首先是数据库。如果我对 Entity1ItemsList 的每个项目使用 context.Add() 和 context.SaveChanges(),则导航属性将成功填充。所以我认为关系配置正确。它不仅适用于 bulkinsert。 按照惯例,关系是自动的,但并非总是如此。尤其是在意识到您的Entity2 没有导航属性返回Entity1 之后。 您可以添加IncludeGraph 选项并将其设置为true 吗? ...参考下面我的回答。 【参考方案1】:

四处搜索后,我想我找到了解决方案。首先设置如下配置

var bulkConfig = new BulkConfig()

    SetOutputIdentity = true,
    PreserveInsertOrder = true
;

运行初始 bulkconfig 以插入 Entities1List 并从 SQL Server 获取唯一 ID

_context.BulkInsert(Entity1ItemsList, bulkConfig);

现在分配了唯一的主键,以便将它们的值设置为相关实体使用

foreach (var item in Entity1ItemsList)

    item.Entity2Obj.Entity1_ID = item.ID;

这将设置正确的外键值。然后我 BulkInsert Entities2List

var Entities2List = Entity1ItemsList.Select(u => u.Entity2Obj).ToList();
 _context.BulkInsert(Entities2List);

我希望通过仅使用一个 BulkInsert 来实现更简单的操作,它会自动添加所有导航属性而不是 2。但这很有效,而且速度很快。

【讨论】:

这方面有什么更新吗? EF 核心开箱即用 我发现我仍在使用的唯一工作方式是我提到的,在使用实体框架 6.2.0 和 Taneryd.Bulkoperation.EF6 的 c# Asp.net mvc 项目中。如果我将项目迁移到我认为是更好的解决方案的 asp.net 核心,我将采用 EF Core 的方式(正如你提到的)【参考方案2】:

这可能是您要查找的内容,因为您还想插入子属性。

context.BulkInsert(Entity1ItemsList, options =&gt; options.IncludeGraph = true);

您可以进一步阅读here:

【讨论】:

我没有使用这个 BulkInsert。我正在使用这里的github.com/borisdj/EFCore.BulkExtensions,因为您使用的不是免费的!所以我不能使用 IncludeGraph 因为它不可用。我还用属性将我的问题编辑回实体,因为我忘了提及它

以上是关于具有一对一关系的 EF Core 批量插入的主要内容,如果未能解决你的问题,请参考以下文章

对EF Core进行扩展使支持批量操作/复杂查询

EF6.0批量插入

EF中的批量操作

EF批量插入数据耗时对比

EF实现批量插入

JPA/Hibernate 批量(批量)插入