Search code examples
c#.net-coreefcore.bulkextensions

BulkInsertOrUpdate with child entity use of efcore.bulkextensions


I am using BulkInsertOrUpdateAsync method to upsert the 20000 records in net-core 3.0. There is no error at all when doing this. it is upserting all the record with parent and child entity into database.

var bulkConfig = new BulkConfig()
            {
                SetOutputIdentity = true,
                PreserveInsertOrder = true
            };   
var subEntities = new List<ItemHistory>(); 
await _dbContext.BulkInsertOrUpdateAsync(entities, bulkConfig);
    
foreach (var entity in entities)
{
   foreach (var subEntity in entity.ItemHistories)
    {
     subEntity.ItemId = entity.ID; // setting FK to match its linked PK that was generated in DB
    }
    subEntities.AddRange(entity.ItemHistories);
}
await _airportDBContext.BulkInsertOrUpdateAsync(subEntities})

But when I am checking the records into database, many of the records having the child entity is referring wrong 'ItemId'. Even when I am executing this again with existing record, it is inserting some of the records again into child entity. while for the parent entity is working fine in both of the scenario. Is there any issue in my code? Or is it a known issue with this package?

I am referring this https://github.com/borisdj/EFCore.BulkExtensions#read-example

and it might be same as this issue:- https://www.bountysource.com/issues/76836788-bulkinsertorupdateasync-ids-not-setting-correctly

Could you anyone having idea to overcome this problem.


Solution

  • Here is answer for this

    var bulkConfig = new BulkConfig()
                {
                    SetOutputIdentity = true,
                    PreserveInsertOrder = true
                };   
    var subEntities = new List<ItemHistory>(); 
    entities = entities.ForEach(i => i.ID == 0);
    await _dbContext.BulkInsertOrUpdateAsync(entities, bulkConfig);
    
        
    foreach (var entity in entities)
    {
       foreach (var subEntity in entity.ItemHistories)
        {
         subEntity.ItemId = entity.ID; // setting FK to match its linked PK that was generated in DB
        }
        subEntities.AddRange(entity.ItemHistories);
    }
    await _airportDBContext.BulkInsertOrUpdateAsync(subEntities});