Skip to content

Commit

Permalink
Don't call local DetectChanges in cascade processing if AutoDetectCha…
Browse files Browse the repository at this point in the history
…ngesEnabled is false (#28402)
  • Loading branch information
ajcvickers authored Jul 12, 2022
1 parent c146f7a commit 78237c3
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 1 deletion.
8 changes: 7 additions & 1 deletion src/EFCore/ChangeTracking/Internal/StateManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1087,6 +1087,9 @@ public virtual void CascadeDelete(InternalEntityEntry entry, bool force, IEnumer
var doCascadeDelete = force || CascadeDeleteTiming != CascadeTiming.Never;
var principalIsDetached = entry.EntityState == EntityState.Detached;

var detectChangesEnabled = Context.ChangeTracker.AutoDetectChangesEnabled
&& !((IRuntimeModel)Model).SkipDetectChanges;

foreignKeys ??= entry.EntityType.GetReferencingForeignKeys();
foreach (var fk in foreignKeys)
{
Expand All @@ -1103,7 +1106,10 @@ public virtual void CascadeDelete(InternalEntityEntry entry, bool force, IEnumer
continue;
}

ChangeDetector.DetectChanges(dependent);
if (detectChangesEnabled)
{
ChangeDetector.DetectChanges(dependent);
}

if (dependent.EntityState != EntityState.Deleted
&& dependent.EntityState != EntityState.Detached
Expand Down
35 changes: 35 additions & 0 deletions test/EFCore.Tests/DbContextTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,41 @@ protected internal override void OnConfiguring(DbContextOptionsBuilder optionsBu
.UseInternalServiceProvider(_serviceProvider);
}

[ConditionalTheory]
[InlineData(false)]
[InlineData(true)]
public void DetectChanges_is_called_for_cascade_delete_unless_disabled(bool autoDetectChangesEnabled)
{
var detectedChangesFor = new List<object>();

using var context = new EarlyLearningCenter();
context.ChangeTracker.DetectingEntityChanges += (_, args) =>
{
detectedChangesFor.Add(args.Entry.Entity);
};

context.ChangeTracker.AutoDetectChangesEnabled = autoDetectChangesEnabled;

var products = new List<Product> { new() { Id = 1 }, new() { Id = 2 } };
var category = context.Attach(new Category { Id = 1, Products = products }).Entity;

Assert.Empty(detectedChangesFor);

context.Remove(category);

if (autoDetectChangesEnabled)
{
Assert.Equal(4, detectedChangesFor.Count);
Assert.Contains(products[0], detectedChangesFor);
Assert.Contains(products[1], detectedChangesFor);
Assert.Equal(2, detectedChangesFor.Count(e => ReferenceEquals(e, category)));
}
else
{
Assert.Empty(detectedChangesFor);
}
}

[ConditionalTheory]
[InlineData(false)]
[InlineData(true)]
Expand Down

0 comments on commit 78237c3

Please sign in to comment.