Contains entity state, and an indication wether is has been changed.
コード例 #1
0
ファイル: PostActionHook.cs プロジェクト: visoft/EFHooks
 /// <summary>
 /// Implements the interface.  This causes the hook to only run for objects that are assignable to TEntity.
 /// </summary>
 public void HookObject(object entity, HookEntityMetadata metadata)
 {
     if (typeof(TEntity).IsAssignableFrom(entity.GetType()))
     {
         Hook((TEntity)entity, metadata);
     }
 }
コード例 #2
0
ファイル: HookedDbContext.cs プロジェクト: visoft/EFHooks
        /// <summary>
        /// Executes the pre action hooks, filtered by <paramref name="requiresValidation"/>.
        /// </summary>
        /// <param name="modifiedEntries">The modified entries to execute hooks for.</param>
        /// <param name="requiresValidation">if set to <c>true</c> executes hooks that require validation, otherwise executes hooks that do NOT require validation.</param>
        private void ExecutePreActionHooks(IEnumerable <HookedEntityEntry> modifiedEntries, bool requiresValidation)
        {
            foreach (var entityEntry in modifiedEntries)
            {
                var entry = entityEntry;                 //Prevents access to modified closure

                foreach (
                    var hook in
                    PreHooks.Where(x => (x.HookStates & entry.PreSaveState) == entry.PreSaveState &&
                                   x.RequiresValidation == requiresValidation))
                {
                    var metadata = new HookEntityMetadata(entityEntry.PreSaveState, this);
                    hook.HookObject(entityEntry.Entity, metadata);

                    if (metadata.HasStateChanged)
                    {
                        entityEntry.PreSaveState = metadata.State;
                    }
                }
            }
        }
コード例 #3
0
ファイル: HookedDbContext.cs プロジェクト: visoft/EFHooks
        /// <summary>
        /// Saves all changes made in this context to the underlying database.
        /// </summary>
        /// <returns>
        /// The number of objects written to the underlying database.
        /// </returns>
        public override int SaveChanges()
        {
            var modifiedEntries = this.ChangeTracker.Entries()
                                  .Where(x => x.State != EntityState.Unchanged && x.State != EntityState.Detached)
                                  .Select(x => new HookedEntityEntry()
            {
                Entity       = x.Entity,
                PreSaveState = x.State
            })
                                  .ToArray();

            ExecutePreActionHooks(modifiedEntries, false);            //Regardless of validation (executing the hook possibly fixes validation errors)

            var hasValidationErrors = this.Configuration.ValidateOnSaveEnabled && this.ChangeTracker.Entries().Any(x => x.State != EntityState.Unchanged && !x.GetValidationResult().IsValid);
            var hasPostHooks        = this.PostHooks.Any();      // Save this to a local variable since we're checking this again later.

            if (!hasValidationErrors)
            {
                ExecutePreActionHooks(modifiedEntries, true);
            }

            var result = base.SaveChanges();

            if (hasPostHooks)
            {
                foreach (var entityEntry in modifiedEntries)
                {
                    var entry = entityEntry;

                    //Obtains hooks that 'listen' to one or more Entity States
                    foreach (var hook in PostHooks.Where(x => (x.HookStates & entry.PreSaveState) == entry.PreSaveState))
                    {
                        var metadata = new HookEntityMetadata(entityEntry.PreSaveState, this);
                        hook.HookObject(entityEntry.Entity, metadata);
                    }
                }
            }

            return(result);
        }
コード例 #4
0
ファイル: HookedDbContext.cs プロジェクト: Atrejoe/EFHooks
            /// <summary>
            /// Executes the pre action hooks, filtered by <paramref name="requiresValidation"/>.
            /// </summary>
            /// <param name="modifiedEntries">The modified entries to execute hooks for.</param>
            /// <param name="requiresValidation">if set to <c>true</c> executes hooks that require validation, otherwise executes hooks that do NOT require validation.</param>
            private void ExecutePreActionHooks(IEnumerable<HookedEntityEntry> modifiedEntries, bool requiresValidation)
            {
                foreach (var entityEntry in modifiedEntries)
                {
                    var entry = entityEntry; //Prevents access to modified closure

                    foreach (var hook in _ctx.PreHooks.Where(x => (x.HookStates & entry.PreSaveState) == entry.PreSaveState && x.RequiresValidation == requiresValidation))
                    {
                        var metadata = new HookEntityMetadata(entityEntry.PreSaveState, _ctx);
                        hook.HookObject(entityEntry.Entity, metadata);

                        if (metadata.HasStateChanged)
                        {
                            entityEntry.PreSaveState = metadata.State;
                        }
                    }
                }
            }
コード例 #5
0
ファイル: HookedDbContext.cs プロジェクト: Atrejoe/EFHooks
            public void RunPostActionHooks()
            {
                var hasPostHooks = _ctx.PostHooks.Any(); // Save this to a local variable since we're checking this again later.
                if (hasPostHooks)
                {
                    foreach (var entityEntry in _modifiedEntries)
                    {
                        var entry = entityEntry;

                        //Obtains hooks that 'listen' to one or more Entity States
                        foreach (var hook in _ctx.PostHooks.Where(x => (x.HookStates & entry.PreSaveState) == entry.PreSaveState))
                        {
                            var metadata = new HookEntityMetadata(entityEntry.PreSaveState, _ctx);
                            hook.HookObject(entityEntry.Entity, metadata);
                        }
                    }
                }
            }
コード例 #6
0
ファイル: HookedDbContext.cs プロジェクト: Atrejoe/EFHooks
        private void ObjectMaterialized(object sender, ObjectMaterializedEventArgs e)
        {
            var metadata = new HookEntityMetadata(EntityState.Unchanged, this);

            foreach (var postLoadHook in PostLoadHooks)
            {
                postLoadHook.HookObject(e.Entity, metadata);
            }
        }
コード例 #7
0
ファイル: HookedDbContext.cs プロジェクト: volak/EFHooks
        /// <summary>
        /// Executes the pre action hooks, filtered by <paramref name="requiresValidation"/>.
        /// </summary>
        /// <param name="modifiedEntries">The modified entries to execute hooks for.</param>
        /// <param name="requiresValidation">if set to <c>true</c> executes hooks that require validation, otherwise executes hooks that do NOT require validation.</param>
        private void ExecutePreActionHooks(IEnumerable<HookedEntityEntry> modifiedEntries, bool requiresValidation)
        {
            if (!_hooks.Any(h => h is IPreActionHook)) return;

            foreach (var entry in modifiedEntries)
            {
                // For each preaction hook ordered by Order where null values are last (since null means it doesn't matter what order they have)
                foreach (
                    var hook in _hooks.Where( h => h.Hook is IPreActionHook )
                        .Where(x => (x.Hook.HookStates & entry.PreSaveState) == entry.PreSaveState && (x.Hook as IPreActionHook).RequiresValidation == requiresValidation)
                        .OrderByDescending( x => x.Order.HasValue ).ThenBy( x => x.Order )
                        )
                {
                    var metadata = new HookEntityMetadata(entry.PreSaveState, this, entry.Entry);
                    hook.Hook.HookObject(entry.Entry.Entity, metadata);
                }
            }
        }
コード例 #8
0
ファイル: HookedDbContext.cs プロジェクト: volak/EFHooks
        private void ExecutePostActionHooks(IEnumerable<HookedEntityEntry> modifiedEntries)
        {
            if (!_hooks.Any(h => h is IPostActionHook)) return;

            foreach (var entityEntry in modifiedEntries)
            {
                var entry = entityEntry;

                //Obtains hooks that 'listen' to one or more Entity States
                foreach (var hook in _hooks.Where(h => h is IPostActionHook)
                    .Where(x => (x.Hook.HookStates & entry.PreSaveState) == entry.PreSaveState)
                    .OrderByDescending(x => x.Order.HasValue).ThenBy(x => x.Order)
                    )
                {
                    var metadata = new HookEntityMetadata(entry.PreSaveState, this, entry.Entry);
                    hook.Hook.HookObject(entry.Entry.Entity, metadata);
                }
            }
        }
コード例 #9
0
ファイル: HookedDbContext.cs プロジェクト: kmckelvin/EFHooks
        public override int SaveChanges()
        {
            bool hasValidationErrors = this.Configuration.ValidateOnSaveEnabled && this.ChangeTracker.Entries().Any(x => !x.GetValidationResult().IsValid);
            bool hasPostHooks = this.PostHooks.Any(); // save this to a local variable since we're checking this again later.

            var modifiedEntries = hasValidationErrors && !hasPostHooks
                                      ? new HookedEntityEntry[0]
                                      : this.ChangeTracker.Entries()
                                            .Where(x => x.State != EntityState.Unchanged && x.State != EntityState.Detached)
                                            .Select(x => new HookedEntityEntry()
                                                             {
                                                                 Entity = x.Entity,
                                                                 PreSaveState = x.State
                                                             })
                                            .ToArray();

            if (!hasValidationErrors)
            {
                foreach (var entityEntry in modifiedEntries)
                {
                    foreach (var hook in PreHooks.Where(x => x.HookStates == entityEntry.PreSaveState))
                    {
                        var metadata = new HookEntityMetadata(entityEntry.PreSaveState);
                        hook.HookObject(entityEntry.Entity, metadata);

                        if (metadata.HasStateChanged)
                        {
                            entityEntry.PreSaveState = metadata.State;
                        }
                    }
                }
            }

            int result = base.SaveChanges();

            if (hasPostHooks)
            {
                foreach (var entityEntry in modifiedEntries)
                {
                    foreach (var hook in PostHooks.Where(x => x.HookStates == entityEntry.PreSaveState))
                    {
                        var metadata = new HookEntityMetadata(entityEntry.PreSaveState);
                        hook.HookObject(entityEntry.Entity, metadata);
                    }
                }
            }

            return result;
        }
コード例 #10
0
ファイル: PostActionHook.cs プロジェクト: visoft/EFHooks
 /// <summary>
 /// The logic to perform per entity after the registered action gets performed.
 /// This gets run once per entity that has been changed.
 /// </summary>
 public abstract void Hook(TEntity entity, HookEntityMetadata metadata);
コード例 #11
0
        /// <summary>
        /// Saves all changes made in this context to the underlying database.
        /// </summary>
        /// <returns>
        /// The number of objects written to the underlying database.
        /// </returns>
        public override int SaveChanges()
        {
            var modifiedEntries = this.ChangeTracker.Entries()
                                            .Where(x => x.State != EntityState.Unchanged && x.State != EntityState.Detached)
                                            .Select(x => new HookedEntityEntry()
                                            {
                                                Entity = x.Entity,
                                                PreSaveState = x.State
                                            })
                                            .ToArray();

            ExecutePreActionHooks(modifiedEntries, false);//Regardless of validation (executing the hook possibly fixes validation errors)

            var hasValidationErrors = this.Configuration.ValidateOnSaveEnabled && this.ChangeTracker.Entries().Any(x => x.State != EntityState.Unchanged && !x.GetValidationResult().IsValid);
            var hasPostHooks = this.PostHooks.Any(); // Save this to a local variable since we're checking this again later.

            if (!hasValidationErrors)
            {
                ExecutePreActionHooks(modifiedEntries, true);
            }

            var result = base.SaveChanges();

            if (hasPostHooks)
            {
                foreach (var entityEntry in modifiedEntries)
                {
                    var entry = entityEntry;

                    //Obtains hooks that 'listen' to one or more Entity States
                    foreach (var hook in PostHooks.Where(x => (x.HookStates & entry.PreSaveState) == entry.PreSaveState))
                    {
                        var metadata = new HookEntityMetadata(entityEntry.PreSaveState, this);
                        hook.HookObject(entityEntry.Entity, metadata);
                    }
                }
            }

            return result;
        }