/// <summary> /// Creates a scope in which a DbContext instance behaves differently. /// The behaviour is resetted on disposal of the scope to what it was before. /// </summary> /// <param name="ctx">The context instance to change behavior for.</param> /// <param name="deferCommit"> /// Suppresses the execution of <see cref="DbContext.SaveChanges()"/> / <see cref="DbContext.SaveChangesAsync(CancellationToken)"/> /// until this instance is disposed or <see cref="Commit()"/> / <see cref="CommitAsync(CancellationToken)"/> is called explicitly. /// </param> /// <param name="retainConnection"> /// Opens connection and retains it until disposal. May increase load/save performance in large scopes. /// </param> public DbContextScope(HookingDbContext ctx, bool?autoDetectChanges = null, bool?lazyLoading = null, bool?forceNoTracking = null, bool?deferCommit = false, bool retainConnection = false, HookImportance?minHookImportance = null, CascadeTiming?cascadeDeleteTiming = null, CascadeTiming?deleteOrphansTiming = null, bool?autoTransactions = null) { Guard.NotNull(ctx, nameof(ctx)); var changeTracker = ctx.ChangeTracker; _ctx = ctx; _autoDetectChangesEnabled = changeTracker.AutoDetectChangesEnabled; _minHookImportance = ctx.MinHookImportance; _suppressCommit = ctx.SuppressCommit; _lazyLoadingEnabled = changeTracker.LazyLoadingEnabled; _queryTrackingBehavior = changeTracker.QueryTrackingBehavior; _cascadeDeleteTiming = changeTracker.CascadeDeleteTiming; _deleteOrphansTiming = changeTracker.DeleteOrphansTiming; _autoTransactionEnabled = ctx.Database.AutoTransactionsEnabled; _retainConnection = retainConnection; if (autoDetectChanges.HasValue) { changeTracker.AutoDetectChangesEnabled = autoDetectChanges.Value; } if (minHookImportance.HasValue) { ctx.MinHookImportance = minHookImportance.Value; } if (lazyLoading.HasValue) { changeTracker.LazyLoadingEnabled = lazyLoading.Value; } if (forceNoTracking == true) { changeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; } if (deferCommit.HasValue) { ctx.SuppressCommit = deferCommit.Value; } if (cascadeDeleteTiming.HasValue) { changeTracker.CascadeDeleteTiming = cascadeDeleteTiming.Value; } if (deleteOrphansTiming.HasValue) { changeTracker.DeleteOrphansTiming = deleteOrphansTiming.Value; } if (autoTransactions.HasValue) { ctx.Database.AutoTransactionsEnabled = autoTransactions.Value; } if (retainConnection) { ctx.Database.OpenConnection(); } }