private void WriteKeys(AuditEntryState state) { var keys = state.EntityType.KeyMembers; if (keys == null) { return; } var currentValues = state.IsDeleted ? state.ObjectStateEntry.OriginalValues : state.ObjectStateEntry.CurrentValues; foreach (var keyMember in keys) { var auditkey = new AuditKey(); try { var name = keyMember.Name; auditkey.Name = name; auditkey.Type = GetType(keyMember); object value = currentValues.GetValue(name); value = FormatValue(state, name, value); auditkey.Value = value; } catch (Exception ex) { Trace.TraceError(ex.Message); auditkey.Value = _errorText; } state.AuditEntity.Keys.Add(auditkey); } }
/// <summary> /// Updates the <see cref="AuditLog"/> from the current <see cref="ObjectContext"/> changes. /// </summary> /// <param name="auditLog">The audit log.</param> /// <returns></returns> public AuditLog UpdateLog(AuditLog auditLog) { if (auditLog == null) { throw new ArgumentNullException("auditLog"); } // must call to make sure changes are detected ObjectContext.DetectChanges(); var entityState = EntityState.Modified; if (Configuration.IncludeInserts) { entityState = entityState | EntityState.Added; } if (Configuration.IncludeDeletes) { entityState = entityState | EntityState.Deleted; } IEnumerable <ObjectStateEntry> changes = ObjectContext .ObjectStateManager .GetObjectStateEntries(entityState); foreach (ObjectStateEntry objectStateEntry in changes) { if (objectStateEntry.Entity == null) { continue; } Type entityType = objectStateEntry.Entity.GetType(); entityType = ObjectContext.GetObjectType(entityType); if (!Configuration.IsAuditable(entityType)) { continue; } var state = new AuditEntryState(objectStateEntry) { AuditLog = auditLog, ObjectContext = ObjectContext, }; if (WriteEntity(state)) { auditLog.Entities.Add(state.AuditEntity); } } return(auditLog); }
private bool WriteEntity(AuditEntryState state) { if (state.EntityType == null) { return(false); } WriteKeys(state); WriteProperties(state); WriteRelationships(state); return(true); }
private static bool IsLoaded(AuditEntryState state, NavigationProperty navigationProperty, IMemberAccessor accessor) { var relationshipManager = state.ObjectStateEntry.RelationshipManager; var getEntityReference = _relatedAccessor.Value.MakeGenericMethod(accessor.MemberType); var parameters = new[] { navigationProperty.RelationshipType.FullName, navigationProperty.ToEndMember.Name }; var entityReference = getEntityReference.Invoke(relationshipManager, parameters) as EntityReference; return(entityReference != null && entityReference.IsLoaded); }
/// <summary> /// Creates the <see cref="AuditLog"/> from the current <see cref="ObjectContext"/>. /// </summary> /// <returns></returns> public AuditLog CreateLog() { var auditLog = new AuditLog { Date = DateTime.Now, Username = Environment.UserName }; // must call to make sure changes are detected ObjectContext.DetectChanges(); IEnumerable <ObjectStateEntry> changes = ObjectContext .ObjectStateManager .GetObjectStateEntries(EntityState.Added | EntityState.Deleted | EntityState.Modified); foreach (ObjectStateEntry objectStateEntry in changes) { if (objectStateEntry.Entity == null) { continue; } Type entityType = objectStateEntry.Entity.GetType(); entityType = ObjectContext.GetObjectType(entityType); if (!Configuration.IsAuditable(entityType)) { continue; } var state = new AuditEntryState(objectStateEntry) { AuditLog = auditLog, ObjectContext = ObjectContext, }; if (WriteEntity(state)) { auditLog.Entities.Add(state.AuditEntity); } } return(auditLog); }
private object FormatValue(AuditEntryState state, string name, object value) { if (value == null) { return(null); } var valueType = value.GetType(); try { object returnValue = valueType.IsEnum ? Enum.GetName(valueType, value) : value; IMethodAccessor formatMethod = Configuration.GetFormatter(state.ObjectType, name); if (formatMethod == null) { return(returnValue); } var context = new AuditPropertyContext { ValueType = valueType, Entity = state.Entity, Value = returnValue }; try { return(formatMethod.Invoke(null, new[] { context })); } catch { // eat format error? return(returnValue); } } catch (Exception ex) { Trace.TraceError(ex.Message); return(_errorText); } }
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 (NavigationProperty navigationProperty in properties) { if (navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many || navigationProperty.FromEndMember.RelationshipMultiplicity != RelationshipMultiplicity.Many) { continue; } string name = navigationProperty.Name; if (Configuration.IsNotAudited(type, name)) { continue; } var accessor = state.EntityAccessor.Find(name); IMemberAccessor displayMember = Configuration.GetDisplayMember(accessor.MemberType); if (displayMember == null) { continue; // no display property, skip } bool isModified = IsModifed(navigationProperty, modifiedMembers); if (state.IsModified && !isModified && !Configuration.IsAlwaysAudited(type, name)) { continue; // this means the property was not changed, skip it } bool 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; if (isLoaded) { // get value directly from instance to save db call object valueInstance = accessor.GetValue(state.Entity); 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) { object 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); } }
/// <summary> /// Updates the <see cref="AuditLog"/> from the current <see cref="ObjectContext"/> changes. /// </summary> /// <param name="auditLog">The audit log.</param> /// <returns></returns> public AuditLog UpdateLog(AuditLog auditLog) { if (auditLog == null) throw new ArgumentNullException("auditLog"); // must call to make sure changes are detected ObjectContext.DetectChanges(); IEnumerable<ObjectStateEntry> changes = ObjectContext .ObjectStateManager .GetObjectStateEntries(EntityState.Added | EntityState.Deleted | EntityState.Modified) .Where(t => !t.IsRelationship); foreach (ObjectStateEntry objectStateEntry in ObjectContext.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Deleted).Where(t => t.IsRelationship)) { ObjectStateEntry entryLeft = null; ObjectStateEntry entryRight = null; var associationEnds = objectStateEntry.GetAssociationEnds(); NavigationProperty navigationPropertyLeft = objectStateEntry.GetNavigationProperty(associationEnds[0]); NavigationProperty navigationPropertyRight = objectStateEntry.GetNavigationProperty(associationEnds[1]); if (objectStateEntry.State == EntityState.Added) { entryLeft = ObjectContext.ObjectStateManager.GetObjectStateEntry((EntityKey)objectStateEntry.CurrentValues[0]); entryRight = ObjectContext.ObjectStateManager.GetObjectStateEntry((EntityKey)objectStateEntry.CurrentValues[1]); } else if (objectStateEntry.State == EntityState.Deleted) { entryLeft = ObjectContext.ObjectStateManager.GetObjectStateEntry((EntityKey)objectStateEntry.OriginalValues[0]); entryRight = ObjectContext.ObjectStateManager.GetObjectStateEntry((EntityKey)objectStateEntry.OriginalValues[1]); } Type entityTypeLeft = entryLeft.Entity.GetType(); entityTypeLeft = ObjectContext.GetObjectType(entityTypeLeft); if (Configuration.IsAuditable(entityTypeLeft)) { var stateLeft = new AuditEntryState(entryLeft) { AuditLog = auditLog, ObjectContext = ObjectContext, AdditionalModifiedProperty = navigationPropertyLeft, AdditionalModifiedPropertyEnd = ObjectContext.GetObjectByKey(entryRight.EntityKey), AdditionalModifiedPropertyIsAdd = objectStateEntry.State == EntityState.Added }; if (WriteEntity(stateLeft)) auditLog.Entities.Add(stateLeft.AuditEntity); } Type entityTypeRight = entryRight.Entity.GetType(); entityTypeRight = ObjectContext.GetObjectType(entityTypeRight); if (Configuration.IsAuditable(entityTypeRight)) { var stateRight = new AuditEntryState(entryRight) { AuditLog = auditLog, ObjectContext = ObjectContext, AdditionalModifiedProperty = navigationPropertyRight, AdditionalModifiedPropertyEnd = ObjectContext.GetObjectByKey(entryLeft.EntityKey), AdditionalModifiedPropertyIsAdd = objectStateEntry.State == EntityState.Added }; if (WriteEntity(stateRight)) auditLog.Entities.Add(stateRight.AuditEntity); } } foreach (ObjectStateEntry objectStateEntry in changes) { if (objectStateEntry.Entity == null) continue; Type entityType = objectStateEntry.Entity.GetType(); entityType = ObjectContext.GetObjectType(entityType); if (!Configuration.IsAuditable(entityType)) continue; var state = new AuditEntryState(objectStateEntry) { AuditLog = auditLog, ObjectContext = ObjectContext, }; if (WriteEntity(state)) auditLog.Entities.Add(state.AuditEntity); } return auditLog; }
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 (EdmProperty edmProperty in properties) { string name = edmProperty.Name; if (Configuration.IsNotAudited(type, name)) { continue; } bool 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) { object 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 }
private static bool IsLoaded(AuditEntryState state, NavigationProperty navigationProperty, IMemberAccessor accessor) { var relationshipManager = state.ObjectStateEntry.RelationshipManager; var getEntityReference = _relatedAccessor.Value.MakeGenericMethod(accessor.MemberType); var parameters = new[] { navigationProperty.RelationshipType.FullName, navigationProperty.ToEndMember.Name }; var entityReference = getEntityReference.Invoke(relationshipManager, parameters) as EntityReference; return (entityReference != null && entityReference.IsLoaded); }
private static object GetDisplayValue(AuditEntryState state, NavigationProperty navigationProperty, IMemberAccessor displayMember, DbDataRecord values) { if (values == null) return null; var association = navigationProperty.RelationshipType as AssociationType; if (association == null) return null; // only support first constraint var referentialConstraint = association.ReferentialConstraints.FirstOrDefault(); if (referentialConstraint == null) return null; var toProperties = referentialConstraint .ToProperties .Select(p => p.Name) .ToList(); var fromProperties = referentialConstraint .FromProperties .Select(p => p.Name) .ToList(); // make sure key columns match if (fromProperties.Count != toProperties.Count) return null; var edmType = referentialConstraint .FromProperties .Select(p => p.DeclaringType) .FirstOrDefault(); if (edmType == null) return null; var eSql = string.Format("SELECT VALUE t FROM {0} AS t", edmType.Name); var q = state.ObjectContext.CreateQuery<object>(eSql); for (int index = 0; index < fromProperties.Count; index++) { string fromProperty = fromProperties[index]; string toProperty = toProperties[index]; var value = values.GetValue(toProperty); var predicate = string.Format("it.{0} == @{0}", fromProperty); var parameter = new ObjectParameter(fromProperty, value); q = q.Where(predicate, parameter); } q = q.SelectValue<object>("it." + displayMember.Name); return q.FirstOrDefault(); }
private object FormatValue(AuditEntryState state, string name, object value) { if (value == null) return null; var valueType = value.GetType(); try { object returnValue = valueType.IsEnum ? Enum.GetName(valueType, value) : value; IMethodAccessor formatMethod = Configuration.GetFormatter(state.ObjectType, name); if (formatMethod == null) return returnValue; var context = new AuditPropertyContext { ValueType = valueType, Entity = state.Entity, Value = returnValue }; try { return formatMethod.Invoke(null, new[] { context }); } catch { // eat format error? return returnValue; } } catch (Exception ex) { Trace.TraceError(ex.Message); return _errorText; } }
/// <summary> /// Updates the <see cref="AuditLog"/> from the current <see cref="ObjectContext"/> changes. /// </summary> /// <param name="auditLog">The audit log.</param> /// <returns></returns> public AuditLog UpdateLog(AuditLog auditLog) { if (auditLog == null) { throw new ArgumentNullException("auditLog"); } // must call to make sure changes are detected ObjectContext.DetectChanges(); var entityState = EntityState.Modified; if (Configuration.IncludeInserts) { entityState = entityState | EntityState.Added; } if (Configuration.IncludeDeletes) { entityState = entityState | EntityState.Deleted; } IEnumerable <ObjectStateEntry> changes = ObjectContext .ObjectStateManager .GetObjectStateEntries(entityState); foreach (ObjectStateEntry objectStateEntry in changes) { if (objectStateEntry.Entity == null) { continue; } Type entityType = objectStateEntry.Entity.GetType(); entityType = ObjectContext.GetObjectType(entityType); //@BaseEAM: Update audit properties in BaseEntity var baseEntity = objectStateEntry.Entity as BaseEntity; if (baseEntity != null) { if (objectStateEntry.State == EntityState.Added) { baseEntity.CreatedDateTime = baseEntity.ModifiedDateTime = Clock.Now; baseEntity.CreatedUser = baseEntity.ModifiedUser = CurrentUser == null ? "" : CurrentUser.Name; } else if (objectStateEntry.State == EntityState.Modified) { objectStateEntry.SetModifiedProperty("ModifiedDateTime"); objectStateEntry.SetModifiedProperty("ModifiedUser"); objectStateEntry.SetModifiedProperty("Version"); baseEntity.ModifiedDateTime = Clock.Now; baseEntity.ModifiedUser = CurrentUser == null ? "" : CurrentUser.Name; } // increase version for concurrency checking baseEntity.Version = baseEntity.Version + 1; } //@BaseEAM if (!Configuration.IsAuditable(entityType)) { continue; } var state = new AuditEntryState(ObjectContext, objectStateEntry) { AuditLog = auditLog, }; if (WriteEntity(state)) { auditLog.Entities.Add(state.AuditEntity); } } return(auditLog); }
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 (EdmProperty edmProperty in properties) { string name = edmProperty.Name; if (Configuration.IsNotAudited(type, name)) continue; var auditProperty = new AuditProperty(); try { var currentValue = currentValues.GetValue(name); var originalValue = originalValues.GetValue(name); bool isModified = modifiedMembers.Any(m => m == name); if (state.IsModified && !isModified && !Configuration.IsAlwaysAudited(type, name)) continue; // this means the property was not changed, skip it auditProperty.Name = name; auditProperty.Type = GetType(edmProperty); //var currentValue = currentValues.GetValue(name); currentValue = FormatValue(state, name, currentValue); if ((!state.IsModified && currentValue == null) || (originalValue == null && currentValue == null) || currentValue.Equals(originalValue)) continue; // ignore null properties? switch (state.AuditEntity.Action) { case AuditAction.Added: auditProperty.Current = currentValue; break; case AuditAction.Modified: auditProperty.Current = currentValue; if (originalValues != null) { 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 }
private static object GetDisplayValue(AuditEntryState state, NavigationProperty navigationProperty, IMemberAccessor displayMember, DbDataRecord values) { if (values == null) { return(null); } var association = navigationProperty.RelationshipType as AssociationType; if (association == null) { return(null); } // only support first constraint var referentialConstraint = association.ReferentialConstraints.FirstOrDefault(); if (referentialConstraint == null) { return(null); } var toProperties = referentialConstraint .ToProperties .Select(p => p.Name) .ToList(); var fromProperties = referentialConstraint .FromProperties .Select(p => p.Name) .ToList(); // make sure key columns match if (fromProperties.Count != toProperties.Count) { return(null); } var edmType = referentialConstraint .FromProperties .Select(p => p.DeclaringType) .FirstOrDefault(); if (edmType == null) { return(null); } var eSql = string.Format("SELECT VALUE t FROM {0} AS t", edmType.Name); var q = state.ObjectContext.CreateQuery <object>(eSql); for (int index = 0; index < fromProperties.Count; index++) { string fromProperty = fromProperties[index]; string toProperty = toProperties[index]; var value = values.GetValue(toProperty); var predicate = string.Format("it.{0} == @{0}", fromProperty); var parameter = new ObjectParameter(fromProperty, value); q = q.Where(predicate, parameter); } q = q.SelectValue <object>("it." + displayMember.Name); return(q.FirstOrDefault()); }
private void WriteKeys(AuditEntryState state) { var keys = state.EntityType.KeyMembers; if (keys == null) return; var currentValues = state.IsDeleted ? state.ObjectStateEntry.OriginalValues : state.ObjectStateEntry.CurrentValues; foreach (var keyMember in keys) { var auditkey = new AuditKey(); try { var name = keyMember.Name; auditkey.Name = name; auditkey.Type = GetType(keyMember); object value = currentValues.GetValue(name); value = FormatValue(state, name, value); auditkey.Value = value; } catch (Exception ex) { Trace.TraceError(ex.Message); auditkey.Value = _errorText; } state.AuditEntity.Keys.Add(auditkey); } }
private bool WriteEntity(AuditEntryState state) { if (state.EntityType == null) return false; WriteKeys(state); WriteProperties(state); WriteRelationships(state); return true; }
/// <summary> /// Updates the <see cref="AuditLog"/> from the current <see cref="ObjectContext"/> changes. /// </summary> /// <param name="auditLog">The audit log.</param> /// <returns></returns> public AuditLog UpdateLog(AuditLog auditLog) { if (auditLog == null) throw new ArgumentNullException("auditLog"); // must call to make sure changes are detected ObjectContext.DetectChanges(); var entityState = EntityState.Modified; if (Configuration.IncludeInserts) entityState = entityState | EntityState.Added; if (Configuration.IncludeDeletes) entityState = entityState | EntityState.Deleted; IEnumerable<ObjectStateEntry> changes = ObjectContext .ObjectStateManager .GetObjectStateEntries(entityState); foreach (ObjectStateEntry objectStateEntry in changes) { if (objectStateEntry.Entity == null) continue; Type entityType = objectStateEntry.Entity.GetType(); entityType = ObjectContext.GetObjectType(entityType); if (!Configuration.IsAuditable(entityType)) continue; var state = new AuditEntryState(ObjectContext, objectStateEntry) { AuditLog = auditLog, }; if (WriteEntity(state)) auditLog.Entities.Add(state.AuditEntity); } return auditLog; }
private static object GetDisplayValue(AuditEntryState state, NavigationProperty navigationProperty, IMemberAccessor displayMember, DbDataRecord values) { if (values == null) { return(null); } var association = navigationProperty.RelationshipType as AssociationType; if (association == null) { return(null); } // only support first constraint var referentialConstraint = association.ReferentialConstraints.FirstOrDefault(); if (referentialConstraint == null) { return(null); } var toProperties = referentialConstraint .ToProperties .Select(p => p.Name) .ToList(); var fromProperties = referentialConstraint .FromProperties .Select(p => p.Name) .ToList(); // make sure key columns match if (fromProperties.Count != toProperties.Count) { return(null); } var edmType = referentialConstraint .FromProperties .Select(p => p.DeclaringType) .FirstOrDefault(); if (edmType == null) { return(null); } var entitySet = state.ObjectContext.GetEntitySet(edmType.FullName); var sql = new StringBuilder(); sql.Append("SELECT VALUE t.") .Append(displayMember.Name) .Append(" FROM ") .Append(entitySet.Name) .Append(" as t") .Append(" WHERE "); var parameters = new List <ObjectParameter>(); for (int index = 0; index < fromProperties.Count; index++) { if (parameters.Count > 1) { sql.Append(" AND "); } string fromProperty = fromProperties[index]; string toProperty = toProperties[index]; var value = values.GetValue(toProperty); var name = "@" + fromProperty; sql.Append(" t.") .Append(fromProperty) .Append(" == ") .Append(name); parameters.Add(new ObjectParameter(fromProperty, value)); } var q = state.ObjectContext.CreateQuery <object>( sql.ToString(), parameters.ToArray()); return(q.FirstOrDefault()); }
private static object GetDisplayValue(AuditEntryState state, NavigationProperty navigationProperty, IMemberAccessor displayMember, DbDataRecord values) { if (values == null) return null; var association = navigationProperty.RelationshipType as AssociationType; if (association == null) return null; // only support first constraint var referentialConstraint = association.ReferentialConstraints.FirstOrDefault(); if (referentialConstraint == null) return null; var toProperties = referentialConstraint .ToProperties .Select(p => p.Name) .ToList(); var fromProperties = referentialConstraint .FromProperties .Select(p => p.Name) .ToList(); // make sure key columns match if (fromProperties.Count != toProperties.Count) return null; var edmType = referentialConstraint .FromProperties .Select(p => p.DeclaringType) .FirstOrDefault(); if (edmType == null) return null; var entitySet = state.ObjectContext.GetEntitySet(edmType.FullName); var sql = new StringBuilder(); sql.Append("SELECT VALUE t.") .Append(displayMember.Name) .Append(" FROM ") .Append(entitySet.Name) .Append(" as t") .Append(" WHERE "); var parameters = new List<ObjectParameter>(); for (int index = 0; index < fromProperties.Count; index++) { if (index > 0) sql.Append(" AND "); string fromProperty = fromProperties[index]; string toProperty = toProperties[index]; var value = values.GetValue(toProperty); var name = "@" + fromProperty; sql.Append(" t.").Append(fromProperty); if (value != null) { sql.Append(" == ").Append(name); parameters.Add(new ObjectParameter(fromProperty, value)); } else { sql.Append(" is null"); } } var q = state.ObjectContext.CreateQuery<object>( sql.ToString(), parameters.ToArray()); return q.FirstOrDefault(); }
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 (NavigationProperty navigationProperty in properties) { if (navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many || navigationProperty.FromEndMember.RelationshipMultiplicity != RelationshipMultiplicity.Many) continue; string name = navigationProperty.Name; if (Configuration.IsNotAudited(type, name)) continue; var accessor = state.EntityAccessor.Find(name); IMemberAccessor displayMember = Configuration.GetDisplayMember(accessor.MemberType); if (displayMember == null) continue; // no display property, skip bool isModified = IsModifed(navigationProperty, modifiedMembers); if (state.IsModified && !isModified && !Configuration.IsAlwaysAudited(type, name)) continue; // this means the property was not changed, skip it bool 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 object 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) { object 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); } }
/// <summary> /// Creates the <see cref="AuditLog"/> from the current <see cref="ObjectContext"/>. /// </summary> /// <returns></returns> public AuditLog CreateLog() { var auditLog = new AuditLog { Date = DateTime.Now, Username = Environment.UserName }; // must call to make sure changes are detected ObjectContext.DetectChanges(); IEnumerable<ObjectStateEntry> changes = ObjectContext .ObjectStateManager .GetObjectStateEntries(EntityState.Added | EntityState.Deleted | EntityState.Modified); foreach (ObjectStateEntry objectStateEntry in changes) { if (objectStateEntry.Entity == null) continue; Type entityType = objectStateEntry.Entity.GetType(); entityType = ObjectContext.GetObjectType(entityType); if (!Configuration.IsAuditable(entityType)) continue; var state = new AuditEntryState(objectStateEntry) { AuditLog = auditLog, ObjectContext = ObjectContext, }; if (WriteEntity(state)) auditLog.Entities.Add(state.AuditEntity); } return auditLog; }