Beispiel #1
0
        /// <summary>
        /// Sets the configuration values from attribute, local and global
        /// </summary>
        public void SetConfig(IAuditDbContext context)
        {
            var type = context.GetType();

            if (!_auditAttributeCache.ContainsKey(type))
            {
                _auditAttributeCache[type] = type.GetTypeInfo().GetCustomAttribute(typeof(AuditDbContextAttribute)) as AuditDbContextAttribute;
            }
            var attrConfig   = _auditAttributeCache[type]?.InternalConfig;
            var localConfig  = Audit.EntityFramework.Configuration.GetConfigForType(type);
            var globalConfig = Audit.EntityFramework.Configuration.GetConfigForType(typeof(AuditDbContext));

            context.Mode = attrConfig?.Mode ?? localConfig?.Mode ?? globalConfig?.Mode ?? AuditOptionMode.OptOut;
            context.IncludeEntityObjects     = attrConfig?.IncludeEntityObjects ?? localConfig?.IncludeEntityObjects ?? globalConfig?.IncludeEntityObjects ?? false;
            context.ExcludeValidationResults = attrConfig?.ExcludeValidationResults ?? localConfig?.ExcludeValidationResults ?? globalConfig?.ExcludeValidationResults ?? false;
            context.AuditEventType           = attrConfig?.AuditEventType ?? localConfig?.AuditEventType ?? globalConfig?.AuditEventType;
            context.EntitySettings           = MergeEntitySettings(attrConfig?.EntitySettings, localConfig?.EntitySettings, globalConfig?.EntitySettings);
            context.ExcludeTransactionId     = attrConfig?.ExcludeTransactionId ?? localConfig?.ExcludeTransactionId ?? globalConfig?.ExcludeTransactionId ?? false;
#if EF_FULL
            context.IncludeIndependantAssociations = attrConfig?.IncludeIndependantAssociations ?? localConfig?.IncludeIndependantAssociations ?? globalConfig?.IncludeIndependantAssociations ?? false;
#endif
        }
Beispiel #2
0
        /// <summary>
        /// Gets the entities changes for an entry entity.
        /// </summary>
        /// <param name="entry">The entry.</param>
        /// <param name="context">The audit database context.</param>
        private List <EventEntryChange> GetChanges(IAuditDbContext context, DbEntityEntry entry)
        {
            var dbContext = context.DbContext;
            var result    = new List <EventEntryChange>();

            foreach (var propName in entry.CurrentValues.PropertyNames)
            {
                var prop = entry.Property(propName);
                if (prop.IsModified)
                {
                    if (IncludeProperty(context, entry, prop.Name))
                    {
                        var colName = EntityKeyHelper.Instance.GetColumnName(entry.Entity.GetType(), prop.Name, dbContext);

                        var origValue = prop.OriginalValue;
                        var currValue = prop.CurrentValue;
                        result.Add(new EventEntryChange()
                        {
                            ColumnName    = colName,
                            NewValue      = HasPropertyValue(context, entry, prop.Name, currValue, out object outputNewValue) ? outputNewValue : currValue,
                            OriginalValue = HasPropertyValue(context, entry, prop.Name, origValue, out object outputOriValue) ? outputOriValue : origValue
                        });
        /// <summary>
        /// Creates the Audit Event.
        /// </summary>
        public EntityFrameworkEvent CreateAuditEvent(IAuditDbContext context)
        {
            var dbContext       = context.DbContext;
            var modifiedEntries = GetModifiedEntries(context);

            if (modifiedEntries.Count == 0)
            {
                return(null);
            }
            var dbConnection       = IsRelational(dbContext) ? dbContext.Database.GetDbConnection() : null;
            var clientConnectionId = GetClientConnectionId(dbConnection);
            var efEvent            = new EntityFrameworkEvent()
            {
                Entries       = new List <EventEntry>(),
                Database      = dbConnection?.Database,
                ConnectionId  = clientConnectionId,
                TransactionId = GetCurrentTransactionId(dbContext, clientConnectionId)
            };

            foreach (var entry in modifiedEntries)
            {
                var entity            = entry.Entity;
                var validationResults = DbContextHelper.GetValidationResults(entity);
                var entityType        = dbContext.Model.FindEntityType(entry.Entity.GetType());
                efEvent.Entries.Add(new EventEntry()
                {
                    Valid             = validationResults == null,
                    ValidationResults = validationResults?.Select(x => x.ErrorMessage).ToList(),
                    Entity            = context.IncludeEntityObjects ? entity : null,
                    Action            = DbContextHelper.GetStateName(entry.State),
                    Changes           = entry.State == EntityState.Modified ? GetChanges(dbContext, entry) : null,
                    ColumnValues      = GetColumnValues(dbContext, entry),
                    PrimaryKey        = GetPrimaryKey(entityType, entity),
                    Table             = GetEntityName(entityType)
                });
            }
            return(efEvent);
        }
Beispiel #4
0
        // Determines whether to include the entity on the audit log or not
        private bool IncludeEntity(IAuditDbContext context, Type type, AuditOptionMode mode)
        {
#if NET45
            type = ObjectContext.GetObjectType(type);
#endif
            bool?result = EnsureEntitiesIncludeIgnoreAttrCache(type);  //true:excluded false=ignored null=unknown
            if (result == null)
            {
                // No static attributes, check the filters
                var localConfig  = EntityFramework.Configuration.GetConfigForType(context.GetType());
                var globalConfig = EntityFramework.Configuration.GetConfigForType(typeof(AuditDbContext));
                var included     = EvalIncludeFilter(type, localConfig, globalConfig);
                var ignored      = EvalIgnoreFilter(type, localConfig, globalConfig);
                result = included ? true : ignored ? false : (bool?)null;
            }
            if (mode == AuditOptionMode.OptIn)
            {
                // Include only explicitly included entities
                return(result.GetValueOrDefault());
            }
            // Include all, except the explicitly ignored entities
            return(result == null || result.Value);
        }
 /// <summary>
 /// Updates column values and primary keys on the Audit Event after the EF save operation completes.
 /// </summary>
 public void UpdateAuditEvent(EntityFrameworkEvent efEvent, IAuditDbContext context)
 {
     foreach (var efEntry in efEvent.Entries)
     {
         var entry = efEntry.Entry;
         efEntry.PrimaryKey = GetPrimaryKey(context.DbContext, entry);
         foreach (var pk in efEntry.PrimaryKey)
         {
             if (efEntry.ColumnValues.ContainsKey(pk.Key))
             {
                 efEntry.ColumnValues[pk.Key] = pk.Value;
             }
         }
         var fks = GetForeignKeys(context.DbContext, entry);
         foreach (var fk in fks)
         {
             if (efEntry.ColumnValues.ContainsKey(fk.Key))
             {
                 efEntry.ColumnValues[fk.Key] = fk.Value;
             }
         }
     }
 }
Beispiel #6
0
        /// <summary>
        /// Saves the changes asynchronously.
        /// </summary>
        public async Task <int> SaveChangesAsync(IAuditDbContext context, Func <Task <int> > baseSaveChanges)
        {
            var dbContext = context.DbContext;

            if (context.AuditDisabled)
            {
                return(await baseSaveChanges());
            }
            var efEvent = CreateAuditEvent(context);

            if (efEvent == null)
            {
                return(await baseSaveChanges());
            }
            var scope = await CreateAuditScopeAsync(context, efEvent);

            if (context.EarlySavingAudit)
            {
                await SaveScopeAsync(context, scope, efEvent);
            }
            try
            {
                efEvent.Result = await baseSaveChanges();
            }
            catch (Exception ex)
            {
                efEvent.Success      = false;
                efEvent.ErrorMessage = ex.GetExceptionInfo();
                await SaveScopeAsync(context, scope, efEvent);

                throw;
            }
            efEvent.Success = true;
            await SaveScopeAsync(context, scope, efEvent);

            return(efEvent.Result);
        }
Beispiel #7
0
        /// <summary>
        /// Creates the Audit Event.
        /// </summary>
        public EntityFrameworkEvent CreateAuditEvent(IAuditDbContext context)
        {
            var dbContext       = context.DbContext;
            var modifiedEntries = GetModifiedEntries(context);

            if (modifiedEntries.Count == 0)
            {
                return(null);
            }
            var clientConnectionId = GetClientConnectionId(dbContext.Database.Connection);
            var efEvent            = new EntityFrameworkEvent()
            {
                Entries       = new List <EventEntry>(),
                Database      = dbContext.Database.Connection.Database,
                ConnectionId  = clientConnectionId,
                TransactionId = GetCurrentTransactionId(dbContext, clientConnectionId),
                DbContext     = dbContext
            };

            foreach (var entry in modifiedEntries)
            {
                var entity            = entry.Entity;
                var validationResults = entry.GetValidationResult();
                efEvent.Entries.Add(new EventEntry()
                {
                    Valid             = validationResults.IsValid,
                    ValidationResults = validationResults.ValidationErrors.Select(x => x.ErrorMessage).ToList(),
                    Entity            = context.IncludeEntityObjects ? entity : null,
                    Entry             = entry,
                    Action            = GetStateName(entry.State),
                    Changes           = entry.State == EntityState.Modified ? GetChanges(dbContext, entry) : null,
                    Table             = GetEntityName(dbContext, entity),
                    ColumnValues      = GetColumnValues(entry)
                });
            }
            return(efEvent);
        }
Beispiel #8
0
        /// <summary>
        /// Gets the modified entries to process.
        /// </summary>
#if EF_CORE
        public List <EntityEntry> GetModifiedEntries(IAuditDbContext context)
Beispiel #9
0
 public AuditHelper(IAuditDbContext db)
 {
     Db = db;
 }
Beispiel #10
0
        // Determines whether to include the entity on the audit log or not
#if NETCOREAPP1_0
        private bool IncludeEntity(IAuditDbContext context, EntityEntry entry, AuditOptionMode mode)
Beispiel #11
0
 /// <summary>
 /// Saves the scope.
 /// </summary>
 public void SaveScope(IAuditDbContext context, AuditScope scope, EntityFrameworkEvent @event)
 {
     (scope.Event as AuditEventEntityFramework).EntityFrameworkEvent = @event;
     context.OnScopeSaving(scope);
     scope.Save();
 }
Beispiel #12
0
 public DepartmentContext2()
 {
     auditDbContext = new DefaultAuditContext(this);
     auditDbContext.IncludeEntityObjects = true;
     helper.SetConfig(auditDbContext);
 }