diff --git a/.nuget/NuGet.exe b/.nuget/NuGet.exe index f1cec45..c41a0d0 100644 Binary files a/.nuget/NuGet.exe and b/.nuget/NuGet.exe differ diff --git a/CHANGELOG.md b/CHANGELOG.md index 737711e..e9e4fc1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,4 +35,4 @@ ## 2.0.0.0 * **Breaking Changes** - * Upgraded Entity Framework to v6.0.1 - EF6 changed namespaces (e.g. `System.Data` to `System.Data.Entity`) around. Because of this, v2.0+ won't work with EF5. Please continue to use an earlier version for your EF5 projects. +* Upgraded Entity Framework to v6.0.1 - EF6 changed namespaces (e.g. `System.Data` to `System.Data.Entity`) around. Because of this, v2.0+ won't work with EF5. Please continue to use an earlier version for your EF5 projects. \ No newline at end of file diff --git a/EFHooks.NET45/App.config b/EFHooks.NET45/App.config index 037f575..a45d1b5 100644 --- a/EFHooks.NET45/App.config +++ b/EFHooks.NET45/App.config @@ -3,7 +3,6 @@
- @@ -12,8 +11,8 @@ - + \ No newline at end of file diff --git a/EFHooks.NET45/EFHooks.NET45.csproj b/EFHooks.NET45/EFHooks.NET45.csproj index 50de502..4388a4c 100644 --- a/EFHooks.NET45/EFHooks.NET45.csproj +++ b/EFHooks.NET45/EFHooks.NET45.csproj @@ -40,26 +40,17 @@ ..\EFHooks\EFHooks.snk - - False - ..\packages\EntityFramework.6.0.1\lib\net45\EntityFramework.dll + + ..\packages\EntityFramework.6.1.0\lib\net45\EntityFramework.dll - - False - ..\packages\EntityFramework.6.0.1\lib\net45\EntityFramework.SqlServer.dll - - - ..\packages\EntityFramework.SqlServerCompact.6.0.1\lib\net45\EntityFramework.SqlServerCompact.dll + + ..\packages\EntityFramework.6.1.0\lib\net45\EntityFramework.SqlServer.dll - - True - ..\packages\Microsoft.SqlServer.Compact.4.0.8876.1\lib\net40\System.Data.SqlServerCe.dll - @@ -121,10 +112,7 @@ - if not exist "$(TargetDir)x86" md "$(TargetDir)x86" - xcopy /s /y "$(SolutionDir)packages\Microsoft.SqlServer.Compact.4.0.8876.1\NativeBinaries\x86\*.*" "$(TargetDir)x86" - if not exist "$(TargetDir)amd64" md "$(TargetDir)amd64" - xcopy /s /y "$(SolutionDir)packages\Microsoft.SqlServer.Compact.4.0.8876.1\NativeBinaries\amd64\*.*" "$(TargetDir)amd64" + - + + diff --git a/EFHooks/EFHooks.csproj b/EFHooks/EFHooks.csproj index 01824bd..519dbf0 100644 --- a/EFHooks/EFHooks.csproj +++ b/EFHooks/EFHooks.csproj @@ -42,11 +42,11 @@ False - ..\packages\EntityFramework.6.0.1\lib\net40\EntityFramework.dll + ..\packages\EntityFramework.6.1.0\lib\net40\EntityFramework.dll False - ..\packages\EntityFramework.6.0.1\lib\net40\EntityFramework.SqlServer.dll + ..\packages\EntityFramework.6.1.0\lib\net40\EntityFramework.SqlServer.dll diff --git a/EFHooks/HookedDbContext.cs b/EFHooks/HookedDbContext.cs index 3f0cea4..899f61d 100644 --- a/EFHooks/HookedDbContext.cs +++ b/EFHooks/HookedDbContext.cs @@ -2,6 +2,8 @@ using System.Data.Entity; using System.Data.Common; using System.Linq; +using System.Threading; +using System.Threading.Tasks; namespace EFHooks { @@ -113,71 +115,91 @@ public void RegisterHook(IPostActionHook hook) /// /// The number of objects written to the underlying database. /// - 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); - } + public override int SaveChanges() { + var hookExecution = new HookRunner(this); + hookExecution.RunPreActionHooks(); 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); - } - } - } - + hookExecution.RunPostActionHooks(); return result; } - /// - /// Executes the pre action hooks, filtered by . - /// - /// The modified entries to execute hooks for. - /// if set to true executes hooks that require validation, otherwise executes hooks that do NOT require validation. - private void ExecutePreActionHooks(IEnumerable 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; - } - } - } - } - } + + public override async Task SaveChangesAsync(CancellationToken cancellationToken) { + var hookExecution = new HookRunner(this); + hookExecution.RunPreActionHooks(); + var result = await base.SaveChangesAsync(cancellationToken); + hookExecution.RunPostActionHooks(); + return result; + } + + class HookRunner + { + private HookedDbContext ctx; + private HookedEntityEntry[] modifiedEntries; + + public HookRunner(HookedDbContext ctx) { + this.ctx = ctx; + this.modifiedEntries = ctx.ChangeTracker.Entries() + .Where(x => x.State != EntityState.Unchanged && x.State != EntityState.Detached) + .Select(x => new HookedEntityEntry() { + Entity = x.Entity, + PreSaveState = x.State + }) + .ToArray(); + + } + + public void RunPreActionHooks() { + ExecutePreActionHooks(modifiedEntries, false);//Regardless of validation (executing the hook possibly fixes validation errors) + + var hasValidationErrors = ctx.Configuration.ValidateOnSaveEnabled && ctx.ChangeTracker.Entries().Any(x => x.State != EntityState.Unchanged && !x.GetValidationResult().IsValid); + + if (!hasValidationErrors) { + ExecutePreActionHooks(modifiedEntries, true); + } + + } + + + /// + /// Executes the pre action hooks, filtered by . + /// + /// The modified entries to execute hooks for. + /// if set to true executes hooks that require validation, otherwise executes hooks that do NOT require validation. + private void ExecutePreActionHooks(IEnumerable 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; + } + } + } + } + + 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); + } + } + } + + } + } + } } \ No newline at end of file diff --git a/EFHooks/packages.config b/EFHooks/packages.config index 4fef52d..c1904a8 100644 --- a/EFHooks/packages.config +++ b/EFHooks/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/Nuget-Pack.ps1 b/Nuget-Pack.ps1 new file mode 100644 index 0000000..5f8213d --- /dev/null +++ b/Nuget-Pack.ps1 @@ -0,0 +1,4 @@ +$thisDir = (Split-Path $MyInvocation.MyCommand.Path) +Set-Alias nuget "$thisDir/.nuget/Nuget.exe" +nuget update -Self +nuget pack EFHooks.nuspec -Prop Configuration=Release -IncludeReferencedProjects \ No newline at end of file diff --git a/lib/net40/EFHooks.dll b/lib/net40/EFHooks.dll index 3bd1468..92d84e5 100644 Binary files a/lib/net40/EFHooks.dll and b/lib/net40/EFHooks.dll differ diff --git a/lib/net40/EFHooks.pdb b/lib/net40/EFHooks.pdb index de6d248..85e1897 100644 Binary files a/lib/net40/EFHooks.pdb and b/lib/net40/EFHooks.pdb differ diff --git a/lib/net45/EFHooks.dll b/lib/net45/EFHooks.dll index 8f24dd2..5908fe7 100644 Binary files a/lib/net45/EFHooks.dll and b/lib/net45/EFHooks.dll differ diff --git a/lib/net45/EFHooks.pdb b/lib/net45/EFHooks.pdb index 73e6bad..a61ac90 100644 Binary files a/lib/net45/EFHooks.pdb and b/lib/net45/EFHooks.pdb differ