/// <summary> /// The event that triggers when /// the context savechanges method is called /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void CurrentObjectContext_SavingChanges(object sender, EventArgs e) { try { ChangeTracker.DetectChanges(); // Important! System.Data.Entity.Core.Objects.ObjectContext ctx = ((IObjectContextAdapter)this).ObjectContext; List <System.Data.Entity.Core.Objects.ObjectStateEntry> objectStateEntryList = ctx.ObjectStateManager.GetObjectStateEntries(System.Data.Entity.EntityState.Added | System.Data.Entity.EntityState.Modified | System.Data.Entity.EntityState.Deleted) .ToList(); foreach (System.Data.Entity.Core.Objects.ObjectStateEntry entry in objectStateEntryList) { object[] list = entry.Entity.GetType().GetCustomAttributes(false); // Only the models that marked with 'Auditable' attribute will be tracked // Inside the model the properties that need to tracked needed to be marked with // Auditable attribute if (list.Count() == 0 || !((Nido.Common.Utilities.Attributes.AuditableAttribute)(list[0])).DoAudit) { continue; } TypeAttributes te = entry.Entity.GetType().Attributes; AuditTrail audit = new AuditTrail(); audit.RevisionStamp = DateTime.Now; audit.TableName = entry.EntitySet.Name + entry.EntityKey; audit.UserName = UserName; audit.SystemName = SystemName; if (!entry.IsRelationship) { switch (entry.State) { case System.Data.Entity.EntityState.Added: // write log... { audit.NewData = GetEntryValueInString(entry); audit.Actions = AuditActions.I.ToString(); } break; case System.Data.Entity.EntityState.Deleted: // write log... { audit.TablePrimaryId = GetKeyValue(entry); audit.OldData = GetEntryValueInString(entry); audit.Actions = AuditActions.D.ToString(); } break; case System.Data.Entity.EntityState.Modified: { string xmlOld = "<?xml version='1.0' encoding='utf-16'?> <" + (entry.EntitySet).Name + " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema'>"; string xmlNew = "<?xml version='1.0' encoding='utf-16'?> <" + (entry.EntitySet).Name + " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema'>"; PropertyInfo[] propList = entry.Entity.GetType().GetProperties(); Dictionary <string, object> attrList = new Dictionary <string, object>(); foreach (PropertyInfo pInfo in propList) { object[] atts = pInfo.GetCustomAttributes(typeof(AuditableAttribute), false); if (atts.Length > 0) { attrList.Add(pInfo.Name, atts[0]); } } int i = 0; object[] listte = entry.GetUpdatableOriginalValues()[0].GetType().GetCustomAttributes(false); foreach (string propertyName in entry.GetModifiedProperties()) { if (attrList.Keys.Contains(propertyName)) { DbDataRecord original = entry.OriginalValues; string oldValue = original.GetValue( original.GetOrdinal(propertyName)) .ToString(); System.Data.Entity.Core.Objects.CurrentValueRecord current = entry.CurrentValues; string newValue = current.GetValue( current.GetOrdinal(propertyName)) .ToString(); xmlOld += "<" + propertyName + " type='" + original.GetFieldType(i) + "'>" + oldValue + "</" + propertyName + ">"; xmlNew += "<" + propertyName + " type='" + original.GetFieldType(i) + "'>" + newValue + "</" + propertyName + ">"; } i++; } xmlOld += "</" + (entry.EntitySet).Name + ">"; xmlNew += "</" + (entry.EntitySet).Name + ">"; audit.OldData = xmlOld; audit.NewData = xmlNew; audit.TablePrimaryId = GetKeyValue(entry); audit.Actions = AuditActions.U.ToString(); break; } } } AuditTrails.Add(audit); } } catch { // Keep quite... } }