borisdj / EFCore.BulkExtensions

Entity Framework EF Core efcore Bulk Batch Extensions with BulkCopy in .Net for Insert Update Delete Read (CRUD), Truncate and SaveChanges operations on SQL Server, PostgreSQL, MySQL, SQLite
https://codis.tech/efcorebulk
Other
3.67k stars 587 forks source link

BulkSaveChangesAsync leaves tracked entities in state of "Added" even after successful save. #1513

Open dazinator opened 5 months ago

dazinator commented 5 months ago

I am using

await Context.BulkSaveChangesAsync(bulkConfig, cancellationToken: cancellationToken);

This is called within a surrounding transaction which is created like so:

 public async Task ExecuteWithTransaction(Func<Task> action)
    {
        var executionStrategy = Context.Database.CreateExecutionStrategy();
        await executionStrategy.ExecuteAsync(async () =>
        {
            await using var transaction = await Context.Database.BeginTransactionAsync();
            try
            {
                await action(); // it's called here
                await transaction.CommitAsync();
            }
            catch (Exception)
            {
                await transaction.RollbackAsync();
                throw;
            }
        });
    }

There are 9k entities that have been added to the DBContext and these are all successfully inserted and the transaction completes successfully.

However if I then inspect the DbContext change tracker - all 9k entities are still in an Added() state. This means if something else repeats a call to DbContext.SaveChanges within the same scope, it tries to insert the entities and fails as now duplicate keys.

Ideally, BulkSaveChangesAsync should update the entity state to reflect the new state?

Nazarii77 commented 4 months ago

I have the same issue, what SQL version do you have? Mine is 12.0.2000.8 which is SQL Servier 14, I get "Cannot insert duplicate key ....." but I do not have duplicates, I have 35 000 items and I process them by 5000 at a time, on batch 3 or 4 it usually fails and shows some random item every time and says it is a duplicate

dazinator commented 4 months ago

@Nazarii77 I don't think the implementation of BulkSaveChangesAsync is complete due to this issue.

I ended up ditching it and using the BulkInsert method instead.