我正在尝试在 EventEntryChange 对象的 OriginalValue 和 NewValue 属性中(也可能在 ColumnValues 对象中)设置相关实体的名称。我尝试使用像这样的格式和覆盖选项(只是简化的代码来显示它):
Audit.EntityFramework.Configuration.Setup()
.ForContext<AppDbContext>(config => config
.ForEntity<Product>(prodConfig =>
{
prodConfig.Format(x => x.ProductType, value =>
{
// Get name from related object
var name = relatedObject?.Name;
return name ?? value;
});
})
);
在这两种情况下,它将用更新后的值替换 OriginalValue,但 NewValue 和 ColumnValues 条目将重置为外键 ID。这是因为 DbContextHelper 中的这段代码:
/// <summary>
/// Updates column values and primary keys on the Audit Event after the EF save operation completes.
/// </summary>
public void UpdateAuditEvent(EntityFrameworkEvent efEvent, IAuditDbContext context)
{
// Update PK and FK
foreach (var efEntry in efEvent.Entries)
{
var entry = efEntry.Entry;
efEntry.PrimaryKey = GetPrimaryKey(context.DbContext, entry);
foreach (var pk in efEntry.PrimaryKey)
{
if (efEntry.ColumnValues.ContainsKey(pk.Key))
{
efEntry.ColumnValues[pk.Key] = pk.Value;
}
}
var fks = GetForeignKeys(context.DbContext, entry);
foreach (var fk in fks)
{
if (efEntry.ColumnValues.ContainsKey(fk.Key))
{
efEntry.ColumnValues[fk.Key] = fk.Value;
}
var change = efEntry.Changes?.FirstOrDefault(e => e.ColumnName == fk.Key);
if (change != null)
{
change.NewValue = fk.Value;
}
}
}
// Update ConnectionId
var clientConnectionId = TryGetClientConnectionId(context.DbContext);
if (clientConnectionId != null)
{
efEvent.ConnectionId = clientConnectionId;
}
}
老实说,我不太确定为什么要对审计条目执行此操作,但我确信这是有原因的。然而,我仍然试图弄清楚如何让日志记录工作,甚至是类似的东西(例如添加一个单独的更改来保存链接实体的名称)来满足我的需求。
在实体持久化之前 ID 未知的情况下需要
UpdateAuditEvent
方法,例如数据库生成用于插入的 ID 的情况。这就是库在保存实体后尝试更新审核事件 ID 的原因。
可以选择使用自定义 OnSaving 操作(在保存审核事件之前发生)来更新属性。
例如:
Audit.Core.Configuration.AddOnSavingAction(scope =>
{
foreach (var entry in scope.GetEntityFrameworkEvent().Entries)
{
if (entry.EntityType == typeof(Product))
{
entry.ColumnValues["ProductType"] = relatedObject.Name;
foreach (var change in entry.Changes)
{
if (change.ColumnName == nameof(Product.ProductType))
{
change.OriginalValue = relatedObject.Name;
change.NewValue = ...;
}
}
}
}
});