本文介绍了将SaveChange中的新旧值保留为DbEntityEntry.Entity进行审核的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如您所知,我们可以在SaveChange()中审核对象,但是我对已修改"和已删除"实体存在如下问题,

As you know we can Audit object in SaveChange() but I have some problem with Modified and Deleted entities as following,

首先,我使用 Audit.Net (这非常易于使用)进行审核我的对象,以下方法应按以下方式进行审核:

First I am using Audit.Net(this is very simple to use) to Audit my objects the below method should do audit as:

 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,我认为它总是包含当前值.

1- For Added state there is no problem with because I am auditing dbEntry.Entity which I think contains Current Values always.

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

2- For Delete and Modify there is some problems,

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

Delete: I think as I am auditing dbEntry.Entity, it is looking for current value and raise the exception:

修改:如上所述,总是OldValueNewValue总是与CurrentValue相同.

Modify: always OldValue and NewValue always are the same as CurrentValue as I mentioned above.

所以我的主要问题是如何像dbEntry.Entity那样进行删除和修改?

So my main question is How can I do it for Delete and Modify like dbEntry.Entity?

P.S:在使用模块中,我们可以更改审核对象以将NewValue设置为 Audit.Net .

P.S:in Using block we can change audit object to set NewValue as Audit.Net mentioned.

UPDATE1:

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

Even with this code Old and New value always are the same :

 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;
                }

推荐答案

首先,我要感谢 thepirat000 ,它进行了审核.Net库,正如他在GitHub中提到的那样,这是一个非常不错的库,可供审计,

First I should thanks to thepirat000 who made Audit.Net lib, this is very nice lib to Audit with many option as he mentioned in GitHub

但是关于我的问题,这是我第一次覆盖SaveChange(),我也不知道DbEntityEntry对象,但是解决方案似乎很有趣,只需要将CurrentValuesOriginalValues转换为Object(),在修改情况下,我正在通过dbEntry.OriginalValues.ToObject()获取旧值,并在dbEntry.CurrentValues.ToObject()对其进行更改" rel ="nofollow noreferrer" > Audit.Net 范围,仅此而已.

but about my problem, this is my first time to override SaveChange() and I didn't know DbEntityEntry object as well, but the solution seems so funny, just need to convert CurrentValues and OriginalValues to Object(), in modify case I am getting the old value by dbEntry.OriginalValues.ToObject() and change it with dbEntry.CurrentValues.ToObject() in Audit.Net scope, that is all.

  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();

这篇关于将SaveChange中的新旧值保留为DbEntityEntry.Entity进行审核的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-27 10:15