You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Audit.NET的OnEventSaved事件中获取刚保存的AuditLog表主键

问题解答

1. 当前实现的安全性问题

当前通过取最大ID的实现方式完全不安全,存在以下明确问题:

  • 高并发场景下必然出现主键错配:多个请求同时插入AuditLog时,OrderByDescending取最大ID会拿到其他请求刚插入的主键,导致明细关联到错误的审计日志
  • 存在空引用异常风险:如果FirstOrDefault()返回null(比如审计日志插入失败、上下文无对应数据),直接访问.Id会抛出空引用异常
  • 额外增加不必要的数据库查询开销,性能较差

2. 更优实现方案

不需要查询数据库,Audit.NET的EF事件已经内置了本次操作所有实体的元数据,包括插入后自动生成的主键,直接从事件对象中取值即可:

public void ConfigureAuditDetail(AuditScope scope)  
{
    var efEvent = (scope.Event as AuditEventEntityFramework)?.EntityFrameworkEvent;
    if (efEvent == null) return;

    // 从本次操作的实体条目中筛选出刚插入的AuditLog实体
    var auditLogEntry = efEvent.Entries
        .FirstOrDefault(e => e.Action == "Insert" && e.EntityType == typeof(AuditLog).FullName);
    
    if (auditLogEntry == null) return;
    // 直接获取已生成的主键,无数据库查询
    var auditLogId = (int)auditLogEntry.PrimaryKey.First().Value;

    // 后续明细保存逻辑
    // ...
}

如果你的AuditLog是单独插入、不在当前EF事件的Entries中,可以在插入AuditLog时就把生成的ID存入AuditScope的自定义字段,后续直接读取即可:

// 插入AuditLog的逻辑位置
using(var scope = AuditScope.Create("Operation", () => new { /* 自定义字段 */ }))
{
    // 插入AuditLog获取ID后存入自定义字段
    scope.SetCustomField("AuditLogId", newAuditLog.Id);
    // 其他业务逻辑
}

// ConfigureAuditDetail中直接读取
var auditLogId = scope.Event.CustomFields.TryGetValue("AuditLogId", out var idVal) ? (int)idVal : 0;

内容的提问来源于stack exchange,提问作者Tango Down

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 15:42:03