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

.NET 6升级后Audit.EntityFramework配置失效及回退报错问题求助

解决方案

一、适配.NET6的配置逻辑

.NET6采用顶级语句替代原Startup.cs的结构,不能在审计配置初始化阶段直接从app.ApplicationServices获取服务,需改用审计事件上下文的服务提供者来获取ICurrentUser。

二、Audit.EntityFramework 19.x双审计模式配置调整

19.x版本不允许多次调用Audit.Core.Configuration.Setup(),需将全局统一审计表和特定实体历史表的配置合并,通过显式映射+条件判断实现原有双审计逻辑:

完整配置代码示例(Program.cs)

var builder = WebApplication.CreateBuilder(args);

// 注册业务服务(含ICurrentUser)
builder.Services.AddScoped<ICurrentUser>();

// 配置Audit.NET核心逻辑
Audit.Core.Configuration.Setup()
    .UseEntityFramework(ef => ef
        // 默认映射全局审计表AuditLog
        .AuditTypeMapper(t => typeof(AuditLog))
        // 统一处理所有审计实体的填充逻辑
        .AuditEntityAction((auditEvent, entry, entity) =>
        {
            // 从审计事件上下文获取当前用户服务
            var currentUser = auditEvent.ServiceProvider.GetRequiredService<ICurrentUser>();
            
            // 处理特定实体的历史表填充
            if (entity is Table1History table1History && entry.Entity is Table1 table1)
            {
                FillTableHistoryData(table1, table1History);
            }
            else if (entity is Table2History table2History && entry.Entity is Table2 table2)
            {
                FillOtherTableHistoryData(table2, table2History);
            }
            // 处理全局审计表的字段填充
            else if (entity is AuditLog auditLog)
            {
                auditLog.Id = Guid.NewGuid();
                auditLog.AuditData = entry.ToJson();
                auditLog.EntityType = entry.EntityType.Name;
                auditLog.AuditDate = DateTime.UtcNow;
                auditLog.AuditUsername = currentUser.GetUsername();
                auditLog.AuditUserId = currentUser.GetUserId();
                auditLog.EntityId = entry.PrimaryKey.Count > 1 
                    ? string.Join("|", entry.PrimaryKey.Select(pk => pk.Value)) 
                    : entry.PrimaryKey.First().Value.ToString();
                auditLog.Action = entry.Action;
            }
        })
        // 添加特定实体到历史表的显式映射,覆盖默认规则
        .AuditTypeExplicitMapper(mapper => mapper
            .Map<Table1, Table1History>()
            .Map<Table2, Table2History>()
        )
        .IgnoreMatchedProperties(true));

var app = builder.Build();

// 其他中间件配置...
app.Run();

三、回退旧版本的异常修复(不推荐)

若强制回退到16.1.1版本,GetTableName异常是因为旧版本依赖的EF Core API在.NET6中已变更,需自定义表名获取逻辑替代原调用:

private static string GetEntityTableName(DbContext context, Type entityType)
{
    var entityMetadata = context.Model.FindEntityType(entityType);
    var tableName = entityMetadata.GetTableName();
    var schema = entityMetadata.GetSchema();
    return string.IsNullOrEmpty(schema) ? tableName : $"{schema}.{tableName}";
}

注意:旧版本在.NET6下存在诸多兼容性隐患,优先推荐使用19.x版本方案。

四、核心注意事项

  • 确保AuditLog、Table1History、Table2History均已在DbContext中注册对应的DbSet;
  • 19.x版本中AuditTypeExplicitMapper的Map方法不再接收填充委托,统一移至AuditEntityAction中处理;
  • 用DateTime.UtcNow替代DateTime.Now避免时区差异导致的日志时间混乱。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 22:05:56