Entity Framework Plus Audit记录实体属性新旧值始终相同的问题求助
解决方案
核心原因分析
oldValue与newValue一致问题:
你先调用audit.PreSaveChanges(this)捕获状态,紧接着执行base.SaveChanges()——此时EF已经将实体的当前值同步到数据库,同时把实体状态标记为Unchanged。后续调用audit.PostSaveChanges()时,审计系统无法获取修改前的原始值,只能读取到更新后的实体值,导致oldValue和newValue完全相同。移除
IgnorePropertyUnchanged后仅审计主键问题:
当IgnorePropertyUnchanged设为默认的true时,审计系统仅追踪有变更的属性。但由于前面的执行顺序错误,所有属性都被EF判定为未变更,最终只有作为审计标识的主键会被记录。
修复步骤
1. 调整SaveChanges执行逻辑
不要手动拆分Pre/PostSaveChanges,改用AuditManager的封装方法,确保审计系统正确捕获变更前后的状态:
修改后的SaveChanges重载:
public override int SaveChanges() { // 利用全局配置,自动处理审计流程 using (var audit = AuditManager.BeginAudit(this)) { var rowsAffected = base.SaveChanges(); // 触发自动保存逻辑(对应构造函数中的AutoSavePreAction) audit.Save(); return rowsAffected; } }
如果要保留手动实例化Audit的方式,必须确保状态捕获和EF保存的顺序正确:
public override int SaveChanges() { var audit = new Z.EntityFramework.Plus.Audit { Configuration = { IgnorePropertyUnchanged = false } }; // 先捕获所有变更前的状态 audit.PreSaveChanges(this); // 执行保存,EF更新实体状态 var rowsAffected = base.SaveChanges(); // 立即捕获变更后的状态 audit.PostSaveChanges(); // 执行自动保存逻辑 audit.Configuration.AutoSavePreAction?.Invoke(this, audit); if (audit.Configuration.AutoSavePreAction != null) { base.SaveChanges(); } return rowsAffected; }
2. 检查实体变更追踪有效性
- 确保实体的属性为可读写的public属性,EF才能正确追踪其变更;
- 更新实体时,必须先从DbContext中加载原始实体,再修改属性值——不要直接创建新实体并附加到上下文,否则EF无法获取原始值,审计系统也无法生成正确的oldValue。
3. 区分两个忽略配置的差异
IgnoreEntityUnchanged = false:表示即使整个实体没有任何属性变更,也要生成审计记录;IgnorePropertyUnchanged = false:表示即使单个属性没有变更,也要在审计记录中包含该属性的oldValue和newValue。
两者作用范围不同,按需调整即可。
内容的提问来源于stack exchange,提问作者MatejDodevski
相关产品推荐
相关产品推荐

