使用 Audit.EntityFramework,如何将外键的值设置为相关实体上的属性?

问题描述 投票:0回答:1

使用Audit.EntityFramework

我正在尝试在 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;
        }
    }

老实说,我不太确定为什么要对审计条目执行此操作,但我确信这是有原因的。然而,我仍然试图弄清楚如何让日志记录工作,甚至是类似的东西(例如添加一个单独的更改来保存链接实体的名称)来满足我的需求。

c# entity-framework audit.net
1个回答
0
投票

在实体持久化之前 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 = ...;
                }
            }
        }
    }
});
© www.soinside.com 2019 - 2024. All rights reserved.