Z.EntityFramework.Extensions.EFCore批量方法如何触发SaveChanges拦截器
解决Z.EntityFramework.Extensions批量操作不触发审计属性逻辑的问题
你的审计逻辑依赖EF Core的ChangeTracker,但Z.EntityFramework.Extensions的批量操作(如BulkInsert)是直接生成原生SQL执行,不会经过EF的ChangeTracker生命周期,所以不会自动触发SetAuditProperties方法。以下是几种可行的解决方案:
方案1:手动批量预处理审计属性
在调用BulkInsert前,遍历实体列表手动设置审计字段,这是最直接的方式:
// 批量设置审计属性的扩展方法 public static void SetAuditPropertiesForBulk(this IEnumerable<AuditableEntity> entities) { var timestamp = DateTime.UtcNow; foreach (var entity in entities) { entity.CreatedOn = timestamp; entity.UpdatedOn = timestamp; entity.isOnProduction = false; // 针对CepaReception的专属处理逻辑 if (entity is CepaReception recep) { // 这里添加该实体需要的额外操作 } } } // 使用示例 var entitiesToInsert = new List<CepaReception> { /* 待插入实体 */ }; entitiesToInsert.SetAuditPropertiesForBulk(); context.CepaReceptions.BulkInsert(entitiesToInsert);
方案2:利用Z.EntityFramework.Extensions的批量事件拦截
该库提供了批量操作的生命周期事件,可通过配置选项注入审计逻辑:
全局配置(所有批量操作生效)
// 在项目启动阶段(如Program.cs)配置 EntityFrameworkManager.ContextFactory = context => { var options = new BulkOperationOptions(); options.BeforeExecute = operation => { var timestamp = DateTime.UtcNow; // 处理批量插入 if (operation is BulkInsertOperation insertOp) { foreach (var entity in insertOp.Entities.Cast<AuditableEntity>()) { entity.CreatedOn = timestamp; entity.UpdatedOn = timestamp; entity.isOnProduction = false; if (entity is CepaReception recep) { // 专属处理逻辑 } } } // 处理批量更新 else if (operation is BulkUpdateOperation updateOp) { foreach (var entity in updateOp.Entities.Cast<AuditableEntity>()) { entity.UpdatedOn = timestamp; entity.isOnProduction = false; } } // 可扩展处理批量删除等其他操作 }; return options; };
单个批量操作配置
仅针对特定BulkInsert生效:
var options = new BulkInsertOptions(); options.BeforeExecute = operation => { var timestamp = DateTime.UtcNow; foreach (var entity in operation.Entities.Cast<AuditableEntity>()) { entity.CreatedOn = timestamp; entity.UpdatedOn = timestamp; entity.isOnProduction = false; if (entity is CepaReception recep) { // 专属处理逻辑 } } }; context.CepaReceptions.BulkInsert(entitiesToInsert, options);
方案3:封装自定义批量操作方法
把审计逻辑和批量操作封装在一起,避免重复代码:
public static void BulkInsertWithAudit<T>(this DbSet<T> dbSet, IEnumerable<T> entities) where T : AuditableEntity { var timestamp = DateTime.UtcNow; foreach (var entity in entities) { entity.CreatedOn = timestamp; entity.UpdatedOn = timestamp; entity.isOnProduction = false; if (entity is CepaReception recep) { // 专属处理逻辑 } } dbSet.BulkInsert(entities); } // 使用示例 context.CepaReceptions.BulkInsertWithAudit(entitiesToInsert);
内容的提问来源于stack exchange,提问作者Daniel Goldberg
相关产品推荐
相关产品推荐

