diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/ChangeTrackers/AbpEfCoreNavigationHelper.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/ChangeTrackers/AbpEfCoreNavigationHelper.cs index 63ddc222bd..3d7b12f86e 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/ChangeTrackers/AbpEfCoreNavigationHelper.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/ChangeTrackers/AbpEfCoreNavigationHelper.cs @@ -31,14 +31,6 @@ public class AbpEfCoreNavigationHelper : ITransientDependency protected virtual void EntityEntryTrackedOrStateChanged(EntityEntry entityEntry) { - if (entityEntry.State is EntityState.Unchanged or EntityState.Modified) - { - foreach (var entry in EntityEntries.Values.Where(x => x.NavigationEntries.Any())) - { - entry.UpdateNavigationEntries(); - } - } - if (entityEntry.State != EntityState.Unchanged) { return; @@ -58,23 +50,11 @@ public class AbpEfCoreNavigationHelper : ITransientDependency EntityEntries.Add(entryId, new AbpEntityEntry(entryId, entityEntry)); } - protected virtual void DetectChanges(EntityEntry entityEntry) - { - if (entityEntry.State != EntityState.Added && - entityEntry.State != EntityState.Deleted && - entityEntry.State != EntityState.Modified) - { - return; - } - - RecursiveDetectChanges(entityEntry); - } - - protected virtual void RecursiveDetectChanges(EntityEntry entityEntry) + protected virtual void DetectChanges(EntityEntry entityEntry, bool checkEntityEntryState = true) { #pragma warning disable EF1001 var stateManager = entityEntry.Context.GetDependencies().StateManager; - var internalEntityEntityEntry = stateManager.Entries.FirstOrDefault(x => x.Entity == entityEntry.Entity); + var internalEntityEntityEntry = stateManager.TryGetEntry(entityEntry.Entity, throwOnNonUniqueness: false); if (internalEntityEntityEntry == null) { return; @@ -95,15 +75,16 @@ public class AbpEfCoreNavigationHelper : ITransientDependency continue; } - if (!abpEntityEntry.IsModified) + abpEntityEntry.UpdateNavigationEntries(); + if (!abpEntityEntry.IsModified && (!checkEntityEntryState || IsEntityEntryChanged(entityEntry))) { abpEntityEntry.IsModified = true; - RecursiveDetectChanges(abpEntityEntry.EntityEntry); + DetectChanges(abpEntityEntry.EntityEntry, false); } var navigationEntry = abpEntityEntry.NavigationEntries.FirstOrDefault(x => x.NavigationEntry.Metadata is INavigation navigationMetadata && navigationMetadata.ForeignKey == foreignKey) ?? abpEntityEntry.NavigationEntries.FirstOrDefault(x => x.NavigationEntry.Metadata is ISkipNavigation skipNavigationMetadata && skipNavigationMetadata.ForeignKey == foreignKey); - if (navigationEntry != null) + if (navigationEntry != null && IsEntityEntryChanged(entityEntry)) { navigationEntry.IsModified = true; } @@ -134,15 +115,16 @@ public class AbpEfCoreNavigationHelper : ITransientDependency continue; } - if (!abpEntityEntry.IsModified) + abpEntityEntry.UpdateNavigationEntries(); + if (!abpEntityEntry.IsModified && (!checkEntityEntryState || IsEntityEntryChanged(entityEntry))) { abpEntityEntry.IsModified = true; - RecursiveDetectChanges(abpEntityEntry.EntityEntry); + DetectChanges(abpEntityEntry.EntityEntry, false); } var navigationEntry = abpEntityEntry.NavigationEntries.FirstOrDefault(x => x.NavigationEntry.Metadata is INavigation navigationMetadata && navigationMetadata.ForeignKey == inverseForeignKey) ?? abpEntityEntry.NavigationEntries.FirstOrDefault(x => x.NavigationEntry.Metadata is ISkipNavigation skipNavigationMetadata && skipNavigationMetadata.ForeignKey == inverseForeignKey); - if (navigationEntry != null) + if (navigationEntry != null && (!checkEntityEntryState || IsEntityEntryChanged(entityEntry))) { navigationEntry.IsModified = true; } @@ -151,6 +133,13 @@ public class AbpEfCoreNavigationHelper : ITransientDependency #pragma warning restore EF1001 } + protected virtual bool IsEntityEntryChanged(EntityEntry entityEntry) + { + return entityEntry.State == EntityState.Added || + entityEntry.State == EntityState.Deleted || + entityEntry.State == EntityState.Modified; + } + public virtual List GetChangedEntityEntries() { return EntityEntries