Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EFCore BulkInsert with one to one relationship

I'm trying to use bulkinsert from EFCore.BulkExtensions in .NET Core 2.1 with one to one relationships. I have 2 Database Entities

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

Then I insert a list of Entity1 Items

 _context.BulkInsert(Entity1ItemsList);

This only works and inserts Entity1 objects in my database. The associated Entity2 items are not inserted. Is there a way to achieve that?

The navigation properties are automatically created during Scaffold-DbContext (database first)

entity.HasOne(d => d.Entity1 )
    .WithOne(p => p.Entity2)
    .HasForeignKey<Entity2>(d => d.Entity1_ID)
    .OnDelete(DeleteBehavior.ClientSetNull)
    .HasConstraintName("FK_Entity1_Entity2");
like image 786
DKar Avatar asked Apr 23 '20 22:04

DKar


Video Answer


2 Answers

After searching around I think I found the solution. First of all set the following config

var bulkConfig = new BulkConfig()
{
    SetOutputIdentity = true,
    PreserveInsertOrder = true
};

Run the initial bulkconfig to insert the Entities1List and get the unique IDs from SQL Server

_context.BulkInsert(Entity1ItemsList, bulkConfig);

Now the unique primary keys are assigned so to set their values to their related entities use

foreach (var item in Entity1ItemsList)
{
    item.Entity2Obj.Entity1_ID = item.ID;
}

This will set the correct Foreign Key values. Then I BulkInsert the Entities2List

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

I was hoping for something simpler by using only one BulkInsert which will automatically add all the navigation properties instead of 2. But this works and it's fast.

like image 65
DKar Avatar answered Oct 09 '22 21:10

DKar


This is probably what you're looking for since you also want to insert child properties.

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

You can read further here:

like image 32
Mosia Thabo Avatar answered Oct 09 '22 21:10

Mosia Thabo