.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
相关产品推荐
相关产品推荐

