Example #1
0
        /// <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();
            }
        }