Search code examples
c#.netentity-framework-core.net-7.0efcore.bulkextensions

EF Core 7 DbCommandInterceptor does not intercept when used with EFCore.BulkExtensions.BulkInsertOrUpdateAsync


I'm using EF Core 7 on MySql with EFCore.BulkExtensions and I'm calling BulkInsertOrUpdateAsync to Upsert some clients in my database.

public class Client : ITimeEntity
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime CreationDate { get; set; }
    public DateTime ModificationDate { get; set; }
}

I want to update CreationDate and/or ModificationDate based on the operation. If insert set both, if update set only ModificationDate. I have used the below interceptor to achieve this:

public class MyInterceptor : DbCommandInterceptor
{
    public override ValueTask<InterceptionResult<int>> NonQueryExecutingAsync(DbCommand command, 
                                                                              CommandEventData eventData, 
                                                                              InterceptionResult<int> result, 
                                                                              CancellationToken cancellationToken = default)
    {
        var entries = eventData.Context.ChangeTracker.Entries<ITimeEntity>();
        foreach (EntityEntry<IAuditedEntity> entry in entries)
        {
            switch (entry.State)
            {
                case EntityState.Added:
                    entry.Entity.CreationDate = DateTime.UtcNow;
                    entry.Entity.ModificationDate = DateTime.UtcNow;
                    break;
                case EntityState.Modified:
                    entry.Entity.ModificationDate = DateTime.UtcNow;
                    break;
            }
        }
        return base.NonQueryExecutingAsync(command, eventData, result, cancellationToken);
    }
}

But I can see that the entries is empty. How can I achieve this


Solution

  • Since EFCore.BulkExtensions package seems to not use ChangeTracker in this case you can workaround by manually assigning the CreationDate and ModificationDate to all the bulk processed data and then exclude the creation date for on update. Something along these lines:

    // set the CreationDate and ModificationDate
    // ...
    ctx.BulkInsertOrUpdateAsync(..., config => config.PropertiesToExcludeOnUpdate.Add("CreationDate"))