@@ -22,6 +22,7 @@ public class StateManager : IStateManager
2222 private IIdentityMap ? _identityMap1 ;
2323 private Dictionary < IKey , IIdentityMap > ? _identityMaps ;
2424 private bool _needsUnsubscribe ;
25+ private bool _hasServiceProperties ;
2526 private IChangeDetector ? _changeDetector ;
2627
2728 private readonly IDiagnosticsLogger < DbLoggerCategory . ChangeTracking > _changeTrackingLogger ;
@@ -361,6 +362,11 @@ public virtual InternalEntityEntry StartTrackingFromQuery(
361362 _needsUnsubscribe = true ;
362363 }
363364
365+ if ( newEntry . EntityType . HasServiceProperties ( ) )
366+ {
367+ _hasServiceProperties = true ;
368+ }
369+
364370 return newEntry ;
365371 }
366372
@@ -600,6 +606,11 @@ public virtual InternalEntityEntry StartTracking(InternalEntityEntry entry)
600606 _needsUnsubscribe = true ;
601607 }
602608
609+ if ( entry . EntityType . HasServiceProperties ( ) )
610+ {
611+ _hasServiceProperties = true ;
612+ }
613+
603614 return entry ;
604615 }
605616
@@ -661,7 +672,7 @@ public virtual void StopTracking(InternalEntityEntry entry, EntityState oldState
661672 /// any release. You should only use it directly in your code with extreme caution and knowing that
662673 /// doing so can result in application failures when updating to a new Entity Framework Core release.
663674 /// </summary>
664- public virtual void Unsubscribe ( )
675+ public virtual void Unsubscribe ( bool resetting )
665676 {
666677 if ( _needsUnsubscribe )
667678 {
@@ -670,6 +681,27 @@ public virtual void Unsubscribe()
670681 _internalEntityEntrySubscriber . Unsubscribe ( entry ) ;
671682 }
672683 }
684+
685+ if ( _hasServiceProperties )
686+ {
687+ foreach ( var entry in Entries )
688+ {
689+ foreach ( var serviceProperty in entry . EntityType . GetServiceProperties ( ) )
690+ {
691+ var service = entry [ serviceProperty ] ;
692+ if ( resetting
693+ && service is IDisposable disposable )
694+ {
695+ disposable . Dispose ( ) ;
696+ }
697+ else if ( ! ( service is IInjectableService detachable )
698+ || detachable . Detaching ( Context , entry . Entity ) )
699+ {
700+ entry [ serviceProperty ] = null ;
701+ }
702+ }
703+ }
704+ }
673705 }
674706
675707 /// <summary>
@@ -680,7 +712,7 @@ public virtual void Unsubscribe()
680712 /// </summary>
681713 public virtual void ResetState ( )
682714 {
683- Clear ( ) ;
715+ Clear ( resetting : true ) ;
684716 Dependencies . NavigationFixer . AbortDelayedFixup ( ) ;
685717 _changeDetector ? . ResetState ( ) ;
686718
@@ -696,9 +728,9 @@ public virtual void ResetState()
696728 /// any release. You should only use it directly in your code with extreme caution and knowing that
697729 /// doing so can result in application failures when updating to a new Entity Framework Core release.
698730 /// </summary>
699- public virtual void Clear ( )
731+ public virtual void Clear ( bool resetting )
700732 {
701- Unsubscribe ( ) ;
733+ Unsubscribe ( resetting ) ;
702734 ChangedCount = 0 ;
703735 _entityReferenceMap . Clear ( ) ;
704736 _referencedUntrackedEntities = null ;
@@ -708,6 +740,7 @@ public virtual void Clear()
708740 _identityMap1 ? . Clear ( ) ;
709741
710742 _needsUnsubscribe = false ;
743+ _hasServiceProperties = false ;
711744
712745 SavingChanges = false ;
713746
0 commit comments