【问题标题】:Hold Old and New value in SaveChange as DbEntityEntry.Entity to Audit将 SaveChange 中的旧值和新值保存为 DbEntityEntry.Entity 以进行审计
【发布时间】:2017-09-13 23:03:33
【问题描述】:

如您所知,我们可以审核 SaveChange() 中的对象,但我对修改和删除的实体有一些问题,如下所示,

首先我使用Audit.Net(这很容易使用)来审核我的对象,下面的方法应该进行审核:

 private int SaveAuditRecord(DbEntityEntry dbEntry, string userGUID)
    {
        Logging.Log(LoggingMode.Error, "Saving Audid Entry{0}....", dbEntry.ToString());
        DateTime changeTime = DateTime.UtcNow;
        TableAttribute tableAttr = dbEntry.Entity.GetType().GetCustomAttributes(typeof(TableAttribute), true).SingleOrDefault() as TableAttribute;
        string tableName = tableAttr != null ? tableAttr.Name : dbEntry.Entity.GetType().Name;
        Logging.Log(LoggingMode.Error, "TableName Retrived {0}...", tableName);
        switch (dbEntry.State)
        {
            case System.Data.Entity.EntityState.Added:
                int result = base.SaveChanges(); 
                AuditNet.AuditMonoAction("Add " + tableName, userGUID, dbEntry.Entity);
                return result;
            case System.Data.Entity.EntityState.Deleted:
                AuditNet.AuditMonoAction("Delete " + tableName, userGUID, dbEntry.Entity);
                break;
            case System.Data.Entity.EntityState.Modified:
                int modifiedResult = 0;
                var primaryKey = GetPrimaryKeyValue(dbEntry);
                modifiedResult = base.SaveChanges(); 
                object entity2Audit = dbEntry.Entity;//Hold the current entity here and change it in below Audit using block
                using (var audit = Audit.Core.AuditScope.Create("Edit " + tableName, () => dbEntry.Entity))
                { 
                    audit.SetCustomField("UserGUID", userGUID, false);  
                    foreach (var prop in dbEntry.OriginalValues.PropertyNames)
                    {
                        var originalValue = dbEntry.OriginalValues[prop].ToString();
                        var currentValue = dbEntry.CurrentValues[prop].ToString();
                        if (originalValue != currentValue)
                            Logging.Log(LoggingMode.Error, "Prop {0} get originalValue :{1} , currentValue:{2}", prop, originalValue, currentValue);
                    } 
                }
                return modifiedResult;
            default:
                break;
        }
        return base.SaveChanges();
    }

1- 对于添加状态没有问题,因为我正在审核 dbEntry.Entity,我认为它始终包含当前值。

2- 对于DeleteModify 存在一些问题,

删除:我认为在审核 dbEntry.Entity 时,它正在寻找当前值并引发异常:

CurrentValues 不能用于处于 Deleted 状态的实体。

修改:总是OldValueNewValue 总是和上面提到的CurrentValue 一样。

所以我的主要问题是如何像dbEntry.Entity 这样的删除和修改操作?

附注: 在 Using 块中,我们可以更改审计对象以将 NewValue 设置为提到的Audit.Net

更新1:

即使使用此代码,旧值和新值也始终相同:

 int modRes = 0;
                object entity2Audit = dbEntry.Entity;//Hold the current entity here and change it in below Audit using block
                DbEntityEntry dbEntryTemp = dbEntry;
                foreach (var prop in dbEntryTemp.OriginalValues.PropertyNames)
                {
                    var originalValue = dbEntry.OriginalValues[prop].ToString();
                    var currentValue = dbEntry.CurrentValues[prop].ToString();
                    if (originalValue != currentValue)
                    {
                        Logging.Log(LoggingMode.Error, "Prop11 {0} get originalValue :{1} , currentValue:{2}", prop, originalValue, currentValue);
                        dbEntryTemp.CurrentValues[prop] = dbEntryTemp.OriginalValues[prop] = originalValue;
                    }
                } 
                object en = dbEntryTemp.Entity;
                using (var audit = Audit.Core.AuditScope.Create("Edit " + tableName, () => en))
                {
                    modRes = base.SaveChanges();
                    audit.SetCustomField("UserGUID", userGUID, false);
                    audit.SetCustomField("NewValue", dbEntry.Entity, false);
                    audit.SetCustomField("OldValue", en, false);
                    en = dbEntry.Entity;
                }

【问题讨论】:

  • 已解决,但明天可以作为答案发布!!!

标签: c# entity-framework ef-code-first audit audit.net


【解决方案1】:

首先我要感谢 thepirat000,他制作了 Audit.Net 库,这是一个非常好的库,可用于审计,他在 GitHub 中提到了许多选项

但是关于我的问题,这是我第一次覆盖SaveChange(),我也不知道DbEntityEntry 对象,但是解决方案看起来很有趣,只需将CurrentValuesOriginalValues 转换为Object(),在修改情况下,我通过dbEntry.OriginalValues.ToObject() 获取旧值并在Audit.Net 范围内使用dbEntry.CurrentValues.ToObject() 更改它,仅此而已。

  Logging.Log(LoggingMode.Prompt, "Saving Audid Entry{0}....", dbEntry.ToString()); 
        TableAttribute tableAttr = dbEntry.Entity.GetType().GetCustomAttributes(typeof(TableAttribute), true).SingleOrDefault() as TableAttribute;
        string tableName = tableAttr != null ? tableAttr.Name : dbEntry.Entity.GetType().Name;
        Logging.Log(LoggingMode.Prompt, "TableName Retrived {0}...", tableName);
        switch (dbEntry.State)
        {
            case System.Data.Entity.EntityState.Added:
                int result = base.SaveChanges();
                object addedObj = dbEntry.Entity;
                using (var audit = Audit.Core.AuditScope.Create("Add " + tableName, () =>addedObj ))
                {
                    audit.SetCustomField("UserGUID", userGUID);
                    addedObj = null;
                } 
                return result;
            case System.Data.Entity.EntityState.Deleted:
                object deletedObj = dbEntry.Entity;
                using (var audit = Audit.Core.AuditScope.Create("Delete " + tableName, () => deletedObj))
                {
                    audit.SetCustomField("UserGUID", userGUID);
                    deletedObj = null;
                }  
                break;
            case System.Data.Entity.EntityState.Modified: 
                object en = dbEntry.OriginalValues.ToObject();
                using (var audit = Audit.Core.AuditScope.Create("Edit " + tableName, () => en))
                {
                    audit.SetCustomField("UserGUID", userGUID);
                    en = dbEntry.CurrentValues.ToObject();
                }
                break;
            default:
                break;
        }
        return base.SaveChanges();

【讨论】:

    猜你喜欢
    • 2017-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-26
    • 1970-01-01
    • 1970-01-01
    • 2021-08-06
    • 1970-01-01
    相关资源
    最近更新 更多