dinhokz
dinhokz

Reputation: 987

EF Core Bulk Insert is not updating the expected database generated IDs

I'm using the EFCore.BulkExtensions lib version 6.7.0 and Entity Framework Core v6.0.13, trying to reproduce the following behaviour explained in the docs:

using (var transaction = context.Database.BeginTransaction())
{
    context.BulkInsert(entities, new BulkConfig { SetOutputIdentity = true });

    foreach (var entity in entities) 
    {
        foreach (var subEntity in entity.ItemHistories) 
        {
            subEntity.ItemId = entity.ItemId; // sets FK to match its linked PK that was generated in DB
        }

        subEntities.AddRange(entity.ItemHistories);
    }

    context.BulkInsert(subEntities);
    transaction.Commit();
}

The entity.ItemId is supposed to be updated with the PK generated by the database.

I couldn't reproduce it with the following code, the result is always: [ENTITY ID]: 0

using (var transaction = dbContext.Database.BeginTransaction())
{
    var entities = entitiesEnumerable.ToList();

    foreach (var e in entities)
    {
        e.Id = default;
    }

    var bulkConfig = new BulkConfig
    {
        SetOutputIdentity = true
    };

    await dbContext.BulkInsertAsync(entities, bulkConfig);

    foreach (var e in entities)
    {
        _logger.LogWarning($"[ENTITY ID]: {e.Id}");
    }

    transaction.Commit();
}

My entity has the following attribute as PK and the underlying database is SQL Server:

[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }

Upvotes: 2

Views: 949

Answers (2)

dinhokz
dinhokz

Reputation: 987

The problem was not in the insertion, but in the query. The entities being inserted were clones of existing records. So the EF was keeping track of the instances as if I was updating them, instead of creating new records.

The solution was to use the extension method AsNoTracking when querying the original data.

Upvotes: 0

borisdj
borisdj

Reputation: 2529

Try to move transaction.Commit(); before last foreach loop. For other Q, you can make and issue on the Git repo.

Upvotes: 0

Related Questions