具有一对一关系的 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
项目设置了数据?
这里是经验法则:确保在 Entity1
和 Entity2
之间正确配置了您的关系...这可能意味着使用 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 => options.IncludeGraph = true);
您可以进一步阅读here:
【讨论】:
我没有使用这个 BulkInsert。我正在使用这里的github.com/borisdj/EFCore.BulkExtensions,因为您使用的不是免费的!所以我不能使用 IncludeGraph 因为它不可用。我还用属性将我的问题编辑回实体,因为我忘了提及它以上是关于具有一对一关系的 EF Core 批量插入的主要内容,如果未能解决你的问题,请参考以下文章