private void WriteRelationships(AuditEntryState state) { if (!Configuration.IncludeRelationships) { return; } var properties = state.EntityType.NavigationProperties; if (properties.Count == 0) { return; } var modifiedMembers = state.ObjectStateEntry .GetModifiedProperties() .ToList(); var type = state.ObjectType; var currentValues = state.IsDeleted ? state.ObjectStateEntry.OriginalValues : state.ObjectStateEntry.CurrentValues; var originalValues = state.IsModified ? state.ObjectStateEntry.OriginalValues : null; foreach (var navigationProperty in properties) { if (navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many || navigationProperty.FromEndMember.RelationshipMultiplicity != RelationshipMultiplicity.Many) { continue; } var name = navigationProperty.Name; if (Configuration.IsNotAudited(type, name)) { continue; } var accessor = state.EntityAccessor.Find(name); var displayMember = Configuration.GetDisplayMember(accessor.MemberType); if (displayMember == null) { continue; // no display property, skip } var isModified = IsModifed(navigationProperty, modifiedMembers); if (state.IsModified && !isModified && !Configuration.IsAlwaysAudited(type, name)) { continue; // this means the property was not changed, skip it } var isLoaded = IsLoaded(state, navigationProperty, accessor); if (!isLoaded && !Configuration.LoadRelationships) { continue; } var auditProperty = new AuditProperty(); try { auditProperty.Name = name; auditProperty.Type = accessor.MemberType.FullName; auditProperty.IsRelationship = true; auditProperty.ForeignKey = GetForeignKey(navigationProperty); object currentValue = null; if (isLoaded) { // get value directly from instance to save db call var valueInstance = accessor.GetValue(state.Entity); if (valueInstance != null) { currentValue = displayMember.GetValue(valueInstance); } } else { // get value from db currentValue = GetDisplayValue(state, navigationProperty, displayMember, currentValues); } // format currentValue = FormatValue(state, name, currentValue); if (!state.IsModified && currentValue == null) { continue; // skip null value } switch (state.AuditEntity.Action) { case AuditAction.Added: auditProperty.Current = currentValue; break; case AuditAction.Modified: auditProperty.Current = currentValue ?? _nullText; if (Configuration.LoadRelationships) { var originalValue = GetDisplayValue(state, navigationProperty, displayMember, originalValues); originalValue = FormatValue(state, name, originalValue); auditProperty.Original = originalValue; } break; case AuditAction.Deleted: auditProperty.Original = currentValue; break; } } catch (Exception ex) { Trace.TraceError(ex.Message); if (state.IsDeleted) { auditProperty.Original = _errorText; } else { auditProperty.Current = _errorText; } } state.AuditEntity.Properties.Add(auditProperty); } }
private void WriteProperties(AuditEntryState state) { var properties = state.EntityType.Properties; if (properties == null) { return; } var modifiedMembers = state.ObjectStateEntry .GetModifiedProperties() .ToList(); var type = state.ObjectType; var currentValues = state.IsDeleted ? state.ObjectStateEntry.OriginalValues : state.ObjectStateEntry.CurrentValues; var originalValues = state.IsModified ? state.ObjectStateEntry.OriginalValues : null; foreach (var edmProperty in properties) { var name = edmProperty.Name; if (Configuration.IsNotAudited(type, name)) { continue; } var isModified = modifiedMembers.Any(m => m == name); if (state.IsModified && !isModified && !Configuration.IsAlwaysAudited(type, name)) { continue; // this means the property was not changed, skip it } var auditProperty = new AuditProperty(); try { auditProperty.Name = name; auditProperty.Type = GetType(edmProperty); var currentValue = currentValues.GetValue(name); currentValue = FormatValue(state, name, currentValue); if (!state.IsModified && currentValue == null) { continue; // ignore null properties? } switch (state.AuditEntity.Action) { case AuditAction.Added: auditProperty.Current = currentValue; break; case AuditAction.Modified: auditProperty.Current = currentValue; if (originalValues != null) { var originalValue = originalValues.GetValue(edmProperty.Name); originalValue = FormatValue(state, name, originalValue); auditProperty.Original = originalValue; } break; case AuditAction.Deleted: auditProperty.Original = currentValue; break; } } catch (Exception ex) { Trace.TraceError(ex.Message); if (state.IsDeleted) { auditProperty.Original = _errorText; } else { auditProperty.Current = _errorText; } } state.AuditEntity.Properties.Add(auditProperty); } // foreach property }