As you know we can Audit object in SaveChange()
but I have some problem with Modified and Deleted entities as following,
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- For Added state there is no problem with because I am auditing dbEntry.Entity
which I think contains Current Values always.
2- For Delete
and Modify
there is some problems,
Delete: I think as I am auditing dbEntry.Entity
, it is looking for current value and raise the exception:
CurrentValues cannot be used for entities in the Deleted state.
Modify: always OldValue
and NewValue
always are the same as CurrentValue
as I mentioned above.
So my main question is How can I do it for Delete and Modify like dbEntry.Entity
?
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;
}