Метод
ExecuteUpdate в EF Core ускоряет массовые обновления, но пропускает перехватчики и события SaveChanges. Это может сломать аудит изменений.Перехватчик
SaveChanges ловит изменения из трекера. Но ExecuteUpdate работает напрямую с БД и игнорирует его:public override async Task<int> SaveChangesAsync(CancellationToken ct = default)
{
// Захватывает изменения от SaveChanges
var entries = ChangeTracker.Entries()
.Where(e => e.State == EntityState.Modified);
// Но не от ExecuteUpdate!
}
Решение через ручной аудит
Добавляйте аудит вручную перед или после
ExecuteUpdate:await context.Products
.Where(p => p.CategoryId == categoryId)
.ExecuteUpdateAsync(s => s
.SetProperty(p => p.Price, newPrice)
.SetProperty(p => p.ModifiedAt, DateTime.UtcNow)
.SetProperty(p => p.ModifiedBy, currentUser));
// Отдельная запись аудита
context.AuditLogs.Add(new AuditLog
{
Action = "BulkPriceUpdate",
EntityType = "Product",
Details = $"Обновил CategoryId={categoryId}, цена={newPrice}"
});
await context.SaveChangesAsync();
Альтернативы для полного аудита
• Триггеры на уровне БД ловят все изменения, включая ExecuteUpdate. Минус — сложнее тестировать и отлаживать.
• Библиотеки расширения EF предлагают BulkUpdate с встроенным аудитом через опции UseAudit.
📍 Навигация: Вакансии • Задачи • Собесы
🐸Библиотека шарписта
#sharp_view