如何从审计日志中获取主键 Table (Audit.Core.Configuration.AddCustomAction(ActionType.OnEventSaved)
How To Get Primary Key From AuditLog Table (Audit.Core.Configuration.AddCustomAction(ActionType.OnEventSaved)
我正在使用此代码块将审核信息保存到详细信息 table。在此保存期间,我需要从刚刚保存的 AuditLog table 记录中获取 PK,以便我可以添加详细记录。
Audit.Core.Configuration.AddCustomAction(ActionType.OnEventSaved, scope =>
{
auditService.ConfigureAuditDetail(scope);
});
由于我只有范围可用,所以我无法找到 AuditLog 实体,除非通过对上下文的查找。在我得到正确的 PK 之前,这是否安全或可以保存另一条记录。
ctx.AuditLog.OrderByDescending(x => x.Id).FirstOrDefault().Id;
有什么办法可以做得更好吗?
public void ConfigureAuditDetail(AuditScope scope)
{
var efEvent = (scope.Event as AuditEventEntityFramework)?.EntityFrameworkEvent;
List<EventEntryChange> currentChanges = new List<EventEntryChange>();
var ctx = efEvent.GetDbContext() as DbContext;
var auditLogId = ctx.AuditLog.OrderByDescending(x => x.Id).FirstOrDefault().Id;
}
如果您可以通过 Entity Framework 访问要保存的实际实体,则可以直接从中提取 ID 或主键值。我使用我写的扩展方法来做到这一点:
public static object GetPrimaryKeyValue(this EntityEntry entry)
{
return entry.Metadata
.FindPrimaryKey().Properties
.Select(property => entry.Property(property.Name).CurrentValue)
.FirstOrDefault(value => value != null);
}
如果您像这样映射您的审计表,那么 AuditLog
有一个集合 AuditLogDetails
:
public class AuditLog
{
public int Id { get; set; }
public ICollection<AuditLogDetail> Details { get; set; }
public string Table { get; set; }
public string Action { get; set; }
}
public class AuditLogDetail
{
public int Id { get; set; }
public int AuditLogId { get; set; }
public string Column { get; set; }
public string Value { get; set; }
}
然后您可以像这样指定 Audit EF 的映射和操作:
Audit.Core.Configuration.Setup()
.UseEntityFramework(ef => ef
.UseDbContext<MyContext>()
.AuditTypeMapper(t => typeof(AuditLog))
.AuditEntityAction<AuditLog>((auditEvent, entry, auditLog) =>
{
auditLog.Table = entry.Table;
auditLog.Action = entry.Action;
auditLog.Details = entry.ColumnValues.Select(c => new AuditLogDetail()
{
Column = c.Key,
Value = c.Value.ToString()
}).ToList();
})
.IgnoreMatchedProperties());
因此审计实体保存在同一个事务中。
我正在使用此代码块将审核信息保存到详细信息 table。在此保存期间,我需要从刚刚保存的 AuditLog table 记录中获取 PK,以便我可以添加详细记录。
Audit.Core.Configuration.AddCustomAction(ActionType.OnEventSaved, scope =>
{
auditService.ConfigureAuditDetail(scope);
});
由于我只有范围可用,所以我无法找到 AuditLog 实体,除非通过对上下文的查找。在我得到正确的 PK 之前,这是否安全或可以保存另一条记录。
ctx.AuditLog.OrderByDescending(x => x.Id).FirstOrDefault().Id;
有什么办法可以做得更好吗?
public void ConfigureAuditDetail(AuditScope scope)
{
var efEvent = (scope.Event as AuditEventEntityFramework)?.EntityFrameworkEvent;
List<EventEntryChange> currentChanges = new List<EventEntryChange>();
var ctx = efEvent.GetDbContext() as DbContext;
var auditLogId = ctx.AuditLog.OrderByDescending(x => x.Id).FirstOrDefault().Id;
}
如果您可以通过 Entity Framework 访问要保存的实际实体,则可以直接从中提取 ID 或主键值。我使用我写的扩展方法来做到这一点:
public static object GetPrimaryKeyValue(this EntityEntry entry)
{
return entry.Metadata
.FindPrimaryKey().Properties
.Select(property => entry.Property(property.Name).CurrentValue)
.FirstOrDefault(value => value != null);
}
如果您像这样映射您的审计表,那么 AuditLog
有一个集合 AuditLogDetails
:
public class AuditLog
{
public int Id { get; set; }
public ICollection<AuditLogDetail> Details { get; set; }
public string Table { get; set; }
public string Action { get; set; }
}
public class AuditLogDetail
{
public int Id { get; set; }
public int AuditLogId { get; set; }
public string Column { get; set; }
public string Value { get; set; }
}
然后您可以像这样指定 Audit EF 的映射和操作:
Audit.Core.Configuration.Setup()
.UseEntityFramework(ef => ef
.UseDbContext<MyContext>()
.AuditTypeMapper(t => typeof(AuditLog))
.AuditEntityAction<AuditLog>((auditEvent, entry, auditLog) =>
{
auditLog.Table = entry.Table;
auditLog.Action = entry.Action;
auditLog.Details = entry.ColumnValues.Select(c => new AuditLogDetail()
{
Column = c.Key,
Value = c.Value.ToString()
}).ToList();
})
.IgnoreMatchedProperties());
因此审计实体保存在同一个事务中。