Skip to content

Commit

Permalink
Additional testing for many-to-many change tracking
Browse files Browse the repository at this point in the history
Part of #19003

Mostly tests, but also fixes to navigation fixup to/from join entities
  • Loading branch information
ajcvickers committed Jul 16, 2020
1 parent c97657e commit 26d9edc
Show file tree
Hide file tree
Showing 9 changed files with 1,776 additions and 164 deletions.
51 changes: 30 additions & 21 deletions src/EFCore/ChangeTracking/Internal/NavigationFixer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -244,8 +244,7 @@ public virtual void NavigationCollectionChanged(

if (navigationBase is ISkipNavigation skipNavigation)
{
var associationEntry = FindAssociationEntry(entry, oldTargetEntry, skipNavigation);
associationEntry?.SetEntityState(EntityState.Deleted);
FindAssociationEntry(entry, oldTargetEntry, skipNavigation)?.SetEntityState(EntityState.Deleted);

if (skipNavigation.Inverse.IsCollection)
{
Expand Down Expand Up @@ -299,7 +298,15 @@ public virtual void NavigationCollectionChanged(

if (associationEntry.EntityState == EntityState.Detached)
{
associationEntry.SetEntityState(EntityState.Added);
try
{
_inFixup = false;
associationEntry.SetEntityState(EntityState.Added);
}
finally
{
_inFixup = true;
}
}

if (skipNavigation.Inverse.IsCollection)
Expand Down Expand Up @@ -569,10 +576,6 @@ public virtual void StateChanged(
{
DeleteFixup(entry);
}
else if (entry.EntityState == EntityState.Deleted)
{
DeleteSkipNavigationFixup(entry);
}
}
finally
{
Expand Down Expand Up @@ -626,12 +629,6 @@ private void DeleteFixup(InternalEntityEntry entry)
}
}
}
}

private void DeleteSkipNavigationFixup(InternalEntityEntry entry)
{
var entityType = entry.EntityType;
var stateManager = entry.StateManager;

foreach (var skipNavigation in entityType.GetSkipNavigations())
{
Expand All @@ -644,11 +641,9 @@ private void DeleteSkipNavigationFixup(InternalEntityEntry entry)
foreach (var otherEntity in others)
{
var otherEntry = stateManager.TryGetEntry(otherEntity, skipNavigation.Inverse.DeclaringEntityType);
if (otherEntry != null)
if (otherEntry != null
&& otherEntry.EntityState != EntityState.Deleted)
{
FindAssociationEntry(entry, otherEntry, skipNavigation)?.SetEntityState(EntityState.Deleted);
RemoveFromCollection(entry, skipNavigation, otherEntry);

if (skipNavigation.Inverse.IsCollection)
{
RemoveFromCollection(otherEntry, skipNavigation.Inverse, entry);
Expand Down Expand Up @@ -867,7 +862,15 @@ private void InitialFixup(

if (associationEntry.EntityState == EntityState.Detached)
{
associationEntry.SetEntityState(EntityState.Added);
try
{
_inFixup = false;
associationEntry.SetEntityState(EntityState.Added);
}
finally
{
_inFixup = true;
}
}

if (skipNavigation.Inverse.IsCollection)
Expand Down Expand Up @@ -912,7 +915,15 @@ private void DelayedFixup(

if (associationEntry.EntityState == EntityState.Detached)
{
associationEntry.SetEntityState(EntityState.Added);
try
{
_inFixup = false;
associationEntry.SetEntityState(EntityState.Added);
}
finally
{
_inFixup = true;
}
}

AddToCollection(referencedEntry, skipNavigation.Inverse, entry, fromQuery);
Expand Down Expand Up @@ -1180,13 +1191,11 @@ private void ConditionallyNullForeignKeyProperties(
case EntityState.Added:
dependentEntry.SetEntityState(EntityState.Detached);
DeleteFixup(dependentEntry);
DeleteSkipNavigationFixup(dependentEntry);
break;
case EntityState.Unchanged:
case EntityState.Modified:
dependentEntry.SetEntityState(EntityState.Deleted);
DeleteFixup(dependentEntry);
DeleteSkipNavigationFixup(dependentEntry);
break;
}
}
Expand Down
19 changes: 11 additions & 8 deletions src/EFCore/ChangeTracking/Internal/StateManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -242,17 +242,20 @@ public virtual InternalEntityEntry GetOrCreateEntry(object entity, IEntityType e
var entry = TryGetEntry(entity, entityType);
if (entry == null)
{
var runtimeEntityType = _model.FindRuntimeEntityType(entity.GetType());
if (runtimeEntityType != null)
if (!entityType.HasSharedClrType)
{
if (!entityType.IsAssignableFrom(runtimeEntityType))
var runtimeEntityType = _model.FindRuntimeEntityType(entity.GetType());
if (runtimeEntityType != null)
{
throw new InvalidOperationException(
CoreStrings.TrackingTypeMismatch(
runtimeEntityType.DisplayName(), entityType.DisplayName()));
}
if (!entityType.IsAssignableFrom(runtimeEntityType))
{
throw new InvalidOperationException(
CoreStrings.TrackingTypeMismatch(
runtimeEntityType.DisplayName(), entityType.DisplayName()));
}

entityType = runtimeEntityType;
entityType = runtimeEntityType;
}
}

if (entityType.FindPrimaryKey() == null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ protected override void ExecuteWithStrategyInTransaction(
Fixture.Reseed();
}

protected override bool SupportsDatabaseDefaults => false;

public class ManyToManyTrackingInMemoryFixture : ManyToManyTrackingFixtureBase
{
protected override ITestStoreFactory TestStoreFactory => InMemoryTestStoreFactory.Instance;
Expand Down
Loading

0 comments on commit 26d9edc

Please sign in to comment.