/// <summary> /// Registers and type for auditing. /// </summary> /// <param name="auditableEntityType">Type to audit, must implement IAuditableEntity.</param> /// <param name="auditEntityType">Type of audit entity, must implement IAuditEntity.</param> public static void RegisterAuditType(Type auditableEntityType, Type auditEntityType) { // Basic parameter validation. if (auditableEntityType == null) { throw new ArgumentNullException("auditableEntityType"); } if (auditTypes.ContainsKey(auditableEntityType)) { throw new ArgumentException("Type already registered for auditing.", "auditableEntityType"); } // Validate the entity. var iface = auditableEntityType.GetInterface("IAuditableEntity"); if (iface == null) { throw new ArgumentException("Entity does implement IAuditableEntity", "auditableEntityType"); } AuditTypeInfo info = new AuditTypeInfo { EntityType = auditableEntityType, AuditEntityType = auditEntityType }; // Validate the auditEntity if (auditEntityType != null) { iface = auditEntityType.GetInterface("IAuditEntity"); if (iface == null) { throw new ArgumentException("Entity does implement IAuditEntity", "auditEntityType"); } // Extract the list of properties to audit. var properties = auditEntityType.GetProperties(); var entityProperties = auditableEntityType.GetProperties().ToDictionary(x => x.Name); foreach (var property in properties) { if (entityProperties.ContainsKey(property.Name)) { if (property.PropertyType == entityProperties[property.Name].PropertyType) { info.AuditProperties.Add(property.Name); } } } } // Valid so register. auditTypes.Add(auditableEntityType, info); }
/// <summary> /// Checks the destination object for complex types. Returns a list of fields that are complex types. /// </summary> /// <param name="auditTypeInfo"></param> /// <param name="entityEntry"></param> /// <returns></returns> private ICollection <string> GetComplexTypes(AuditTypeInfo auditTypeInfo, DbEntityEntry entityEntry) { var returnValue = new List <string>(); foreach (string propertyName in auditTypeInfo.AuditProperties) { if (entityEntry.Property(propertyName).GetType().Name.Contains("DbComplexPropertyEntry")) { returnValue.Add(propertyName); } } return(returnValue); }
private IAuditEntity AuditEntity(DbEntityEntry entityEntry, AuditTypeInfo auditTypeInfo, DateTimeOffset auditDateTime, string user) { // Create audit entity. DbSet set = this.Set(auditTypeInfo.AuditEntityType); IAuditEntity auditEntity = set.Create() as IAuditEntity; // Check audit entity for complex types. var complexTypes = GetComplexTypes(auditTypeInfo, entityEntry); //Instantiate complex types. foreach (var field in complexTypes) { var property = auditEntity.GetType().GetProperty(field); var entityType = property.PropertyType; property.SetValue(auditEntity, Activator.CreateInstance(entityType)); } //Attach audit Entity to the context. set.Add(auditEntity); // Copy the properties. DbEntityEntry auditEntityEntry = this.Entry(auditEntity); foreach (string propertyName in auditTypeInfo.AuditProperties) { auditEntityEntry.Property(propertyName).CurrentValue = entityEntry.Property(propertyName).OriginalValue; } // Set the audit columns. auditEntityEntry.Property(AuditUpdatedColumnName).CurrentValue = auditDateTime; auditEntityEntry.Property(AuditUserColumnName).CurrentValue = user; auditEntityEntry.Property(AuditTypeColumnName).CurrentValue = entityEntry.State == EntityState.Modified ? "update" : "delete"; auditEntityEntry.Property(AuditSourceIdColumnName).CurrentValue = entityEntry.OriginalValues.GetValue <int>("Id"); return(auditEntity); }