public override void Required_non_PK_one_to_one_with_alternate_key_are_cascade_detached_when_Added(
     CascadeTiming cascadeDeleteTiming,
     CascadeTiming deleteOrphansTiming)
 {
     base.Required_non_PK_one_to_one_with_alternate_key_are_cascade_detached_when_Added(
         cascadeDeleteTiming, deleteOrphansTiming);
 }
Пример #2
0
    public virtual void Entity_removed_from_navigation_property_binding_list_is_removed_from_nav_property_but_not_marked_Deleted(
        CascadeTiming deleteOrphansTiming)
    {
        using var context = CreateF1Context();
        context.ChangeTracker.DeleteOrphansTiming = deleteOrphansTiming;

        var ferrari = context.Teams.Single(t => t.Id == Team.Ferrari);

        var navBindingList = ((IListSource)ferrari.Drivers).GetList();
        var localDrivers   = context.Drivers.Local;

        var alonso = localDrivers.Single(d => d.Name == "Fernando Alonso");

        navBindingList.Remove(alonso);

        Assert.Contains(alonso, localDrivers);

        context.ChangeTracker.DetectChanges();

        if (deleteOrphansTiming == CascadeTiming.Immediate)
        {
            Assert.DoesNotContain(alonso, localDrivers);
        }
        else
        {
            Assert.Contains(alonso, localDrivers); // Because it is not marked as Deleted
        }

        Assert.False(ferrari.Drivers.Contains(alonso)); // But has been removed from nav prop
    }
Пример #3
0
        public override async Task Load_one_to_one_reference_to_dependent_already_loaded_untyped(
            EntityState state, bool async, CascadeTiming cascadeDeleteTiming)
        {
            await base.Load_one_to_one_reference_to_dependent_already_loaded_untyped(state, async, cascadeDeleteTiming);

            AssertSql("");
        }
        public override void Lazy_load_one_to_one_reference_to_dependent_already_loaded(
            EntityState state, CascadeTiming cascadeDeleteTiming)
        {
            base.Lazy_load_one_to_one_reference_to_dependent_already_loaded(state, cascadeDeleteTiming);

            Assert.Equal("", Sql);
        }
 public override void Required_many_to_one_dependents_with_alternate_key_are_cascade_deleted_in_store(
     CascadeTiming cascadeDeleteTiming,
     CascadeTiming deleteOrphansTiming)
 {
     base.Required_many_to_one_dependents_with_alternate_key_are_cascade_deleted_in_store(
         cascadeDeleteTiming, deleteOrphansTiming);
 }
Пример #6
0
    public override void Lazy_load_many_to_one_reference_to_principal_already_loaded(
        EntityState state,
        CascadeTiming cascadeDeleteTiming)
    {
        base.Lazy_load_many_to_one_reference_to_principal_already_loaded(state, cascadeDeleteTiming);

        AssertSql(@"");
    }
Пример #7
0
        public override async Task Load_collection_using_Query_already_loaded_untyped(
            EntityState state, bool async, CascadeTiming cascadeDeleteTiming)
        {
            await base.Load_collection_using_Query_already_loaded_untyped(state, async, cascadeDeleteTiming);

            AssertSql(
                @"@__p_0='707' (Nullable = true)

SELECT [c].[Id], [c].[ParentId]
FROM [Child] AS [c]
WHERE [c].[ParentId] = @__p_0");
        }
Пример #8
0
        public override async Task Load_one_to_one_reference_to_dependent_using_Query_already_loaded(
            EntityState state, bool async, CascadeTiming cascadeDeleteTiming)
        {
            await base.Load_one_to_one_reference_to_dependent_using_Query_already_loaded(state, async, cascadeDeleteTiming);

            AssertSql(
                @"@__p_0='707' (Nullable = true)

SELECT TOP(2) [s].[Id], [s].[ParentId]
FROM [Single] AS [s]
WHERE [s].[ParentId] = @__p_0");
        }
Пример #9
0
 /// <summary>
 ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
 ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
 ///     any release. You should only use it directly in your code with extreme caution and knowing that
 ///     doing so can result in application failures when updating to a new Entity Framework Core release.
 /// </summary>
 public DbContextPoolConfigurationSnapshot(
     bool autoDetectChangesEnabled,
     QueryTrackingBehavior queryTrackingBehavior,
     bool autoTransactionsEnabled,
     bool autoSavepointsEnabled,
     bool lazyLoadingEnabled,
     CascadeTiming cascadeDeleteTiming,
     CascadeTiming deleteOrphansTiming,
     EventHandler <SavingChangesEventArgs>?savingChanges,
     EventHandler <SavedChangesEventArgs>?savedChanges,
     EventHandler <SaveChangesFailedEventArgs>?saveChangesFailed)
 {
     AutoDetectChangesEnabled = autoDetectChangesEnabled;
     QueryTrackingBehavior    = queryTrackingBehavior;
     AutoTransactionsEnabled  = autoTransactionsEnabled;
     AutoSavepointsEnabled    = autoSavepointsEnabled;
     LazyLoadingEnabled       = lazyLoadingEnabled;
     CascadeDeleteTiming      = cascadeDeleteTiming;
     DeleteOrphansTiming      = deleteOrphansTiming;
     SavingChanges            = savingChanges;
     SavedChanges             = savedChanges;
     SaveChangesFailed        = saveChangesFailed;
 }
Пример #10
0
 public override void Required_non_PK_one_to_one_are_cascade_detached_when_Added(
     CascadeTiming cascadeDeleteTiming,
     CascadeTiming deleteOrphansTiming)
 {
 }
Пример #11
0
 public override void Required_many_to_one_dependents_are_cascade_deleted_in_store(
     CascadeTiming cascadeDeleteTiming,
     CascadeTiming deleteOrphansTiming)
 {
 }
Пример #12
0
 public override void Required_one_to_one_with_alternate_key_are_cascade_deleted_in_store(
     CascadeTiming cascadeDeleteTiming,
     CascadeTiming deleteOrphansTiming)
 {
 }
Пример #13
0
 public override void Optional_many_to_one_dependents_are_orphaned_in_store(
     CascadeTiming cascadeDeleteTiming,
     CascadeTiming deleteOrphansTiming)
 {
 }
Пример #14
0
        public void IsModified_tracks_detects_deletion_of_related_entity(bool useExplicitPk, CascadeTiming cascadeTiming)
        {
            using var context = useExplicitPk ? new ExplicitFreezerContext() : new FreezerContext();

            context.ChangeTracker.CascadeDeleteTiming = cascadeTiming;

            var cherry1 = new Cherry {
                Id = 1
            };
            var cherry2 = new Cherry {
                Id = 2
            };
            var chunky1 = new Chunky {
                Id = 1
            };
            var chunky2 = new Chunky {
                Id = 2
            };

            AttachGraph(context, cherry1, cherry2, chunky1, chunky2);

            var relatedToCherry1 = context.Entry(cherry1).Collection(e => e.Chunkies);
            var relatedToCherry2 = context.Entry(cherry2).Collection(e => e.Chunkies);
            var relatedToChunky1 = context.Entry(chunky1).Collection(e => e.Cherries);
            var relatedToChunky2 = context.Entry(chunky2).Collection(e => e.Cherries);

            Assert.False(relatedToCherry1.IsModified);
            Assert.False(relatedToCherry2.IsModified);
            Assert.False(relatedToChunky1.IsModified);
            Assert.False(relatedToChunky2.IsModified);

            context.Entry(chunky1).State = EntityState.Deleted;

            Assert.True(relatedToCherry1.IsModified);
            Assert.False(relatedToCherry2.IsModified);
            Assert.True(relatedToChunky1.IsModified);
            Assert.False(relatedToChunky2.IsModified);
        }
Пример #15
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?hooksEnabled                 = null,
                              bool?lazyLoading                  = null,
                              bool?forceNoTracking              = null,
                              bool?deferCommit                  = false,
                              bool retainConnection             = false,
                              CascadeTiming?cascadeDeleteTiming = null,
                              CascadeTiming?deleteOrphansTiming = null,
                              bool?autoTransactions             = null)
        {
            Guard.NotNull(ctx, nameof(ctx));

            var changeTracker = ctx.ChangeTracker;

            _ctx = ctx;
            _autoDetectChangesEnabled = changeTracker.AutoDetectChangesEnabled;
            _hooksEnabled             = ctx.HooksEnabled;
            _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 (hooksEnabled.HasValue)
            {
                ctx.HooksEnabled = hooksEnabled.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();
            }
        }
Пример #16
0
 public override void Required_one_to_one_are_cascade_detached_when_Added(
     CascadeTiming cascadeDeleteTiming,
     CascadeTiming deleteOrphansTiming)
 => base.Required_one_to_one_are_cascade_detached_when_Added(cascadeDeleteTiming, deleteOrphansTiming);
Пример #17
0
        public override async Task Load_collection_already_loaded_untyped(EntityState state, bool async, CascadeTiming cascadeDeleteTiming)
        {
            await base.Load_collection_already_loaded_untyped(state, async, cascadeDeleteTiming);

            AssertSql("");
        }
Пример #18
0
        public override void Lazy_load_collection_already_loaded(EntityState state, CascadeTiming cascadeDeleteTiming)
        {
            base.Lazy_load_collection_already_loaded(state, cascadeDeleteTiming);

            Assert.Equal("", Sql);
        }
 public override void Optional_many_to_one_dependents_with_alternate_key_are_orphaned_in_store(
     CascadeTiming cascadeDeleteTiming,
     CascadeTiming deleteOrphansTiming)
 {
     base.Optional_many_to_one_dependents_with_alternate_key_are_orphaned_in_store(cascadeDeleteTiming, deleteOrphansTiming);
 }