/// <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 void DetectNavigationChange(InternalEntityEntry entry, INavigationBase navigationBase) { var snapshotValue = entry.GetRelationshipSnapshotValue(navigationBase); var currentValue = entry[navigationBase]; var stateManager = entry.StateManager; if (navigationBase.IsCollection) { var snapshotCollection = (IEnumerable?)snapshotValue; var currentCollection = (IEnumerable?)currentValue; var removed = new HashSet <object>(LegacyReferenceEqualityComparer.Instance); if (snapshotCollection != null) { foreach (var entity in snapshotCollection) { removed.Add(entity); } } var added = new HashSet <object>(LegacyReferenceEqualityComparer.Instance); if (currentCollection != null) { foreach (var entity in currentCollection) { if (!removed.Remove(entity)) { added.Add(entity); } } } if (added.Count > 0 || removed.Count > 0) { if (_loggingOptions.IsSensitiveDataLoggingEnabled) { if (navigationBase is INavigation navigation) { _logger.CollectionChangeDetectedSensitive(entry, navigation, added, removed); } else if (navigationBase is ISkipNavigation skipNavigation) { _logger.SkipCollectionChangeDetectedSensitive(entry, skipNavigation, added, removed); } } else { if (navigationBase is INavigation navigation) { _logger.CollectionChangeDetected(entry, navigation, added, removed); } else if (navigationBase is ISkipNavigation skipNavigation) { _logger.SkipCollectionChangeDetected(entry, skipNavigation, added, removed); } } stateManager.InternalEntityEntryNotifier.NavigationCollectionChanged(entry, navigationBase, added, removed); } } else if (!ReferenceEquals(currentValue, snapshotValue)) { Check.DebugAssert(navigationBase is INavigation, "Issue #21673. Non-collection skip navigations not supported."); var navigation = (INavigation)navigationBase; if (_loggingOptions.IsSensitiveDataLoggingEnabled) { _logger.ReferenceChangeDetectedSensitive(entry, navigation, snapshotValue, currentValue); } else { _logger.ReferenceChangeDetected(entry, navigation, snapshotValue, currentValue); } stateManager.InternalEntityEntryNotifier.NavigationReferenceChanged(entry, navigation, snapshotValue, currentValue); } }
private void DetectNavigationChange(InternalEntityEntry entry, INavigation navigation) { var snapshotValue = entry.GetRelationshipSnapshotValue(navigation); var currentValue = entry[navigation]; var stateManager = entry.StateManager; if (navigation.IsCollection()) { var snapshotCollection = (IEnumerable)snapshotValue; var currentCollection = (IEnumerable)currentValue; var removed = new HashSet <object>(ReferenceEqualityComparer.Instance); if (snapshotCollection != null) { foreach (var entity in snapshotCollection) { removed.Add(entity); } } var added = new HashSet <object>(ReferenceEqualityComparer.Instance); if (currentCollection != null) { foreach (var entity in currentCollection) { if (!removed.Remove(entity)) { added.Add(entity); } } } if (added.Count > 0 || removed.Count > 0) { if (_loggingOptions.IsSensitiveDataLoggingEnabled) { _logger.CollectionChangeDetectedSensitive(entry, navigation, added, removed); } else { _logger.CollectionChangeDetected(entry, navigation, added, removed); } stateManager.InternalEntityEntryNotifier.NavigationCollectionChanged(entry, navigation, added, removed); } } else if (!ReferenceEquals(currentValue, snapshotValue) && (!navigation.ForeignKey.IsOwnership || !navigation.IsDependentToPrincipal())) { if (_loggingOptions.IsSensitiveDataLoggingEnabled) { _logger.ReferenceChangeDetectedSensitive(entry, navigation, snapshotValue, currentValue); } else { _logger.ReferenceChangeDetected(entry, navigation, snapshotValue, currentValue); } stateManager.InternalEntityEntryNotifier.NavigationReferenceChanged(entry, navigation, snapshotValue, currentValue); } }
private void DetectNavigationChange(InternalEntityEntry entry, INavigationBase navigationBase) { var snapshotValue = entry.GetRelationshipSnapshotValue(navigationBase); var currentValue = entry[navigationBase]; var stateManager = entry.StateManager; if (navigationBase.IsCollection) { var snapshotCollection = (IEnumerable)snapshotValue; var currentCollection = (IEnumerable)currentValue; var removed = new HashSet <object>(LegacyReferenceEqualityComparer.Instance); if (snapshotCollection != null) { foreach (var entity in snapshotCollection) { removed.Add(entity); } } var added = new HashSet <object>(LegacyReferenceEqualityComparer.Instance); if (currentCollection != null) { foreach (var entity in currentCollection) { if (!removed.Remove(entity)) { added.Add(entity); } } } if (added.Count > 0 || removed.Count > 0) { if (_loggingOptions.IsSensitiveDataLoggingEnabled) { if (navigationBase is INavigation navigation) { _logger.CollectionChangeDetectedSensitive(entry, navigation, added, removed); } else if (navigationBase is ISkipNavigation skipNavigation) { _logger.SkipCollectionChangeDetectedSensitive(entry, skipNavigation, added, removed); } } else { if (navigationBase is INavigation navigation) { _logger.CollectionChangeDetected(entry, navigation, added, removed); } else if (navigationBase is ISkipNavigation skipNavigation) { _logger.SkipCollectionChangeDetected(entry, skipNavigation, added, removed); } } stateManager.InternalEntityEntryNotifier.NavigationCollectionChanged(entry, navigationBase, added, removed); } } else if (!ReferenceEquals(currentValue, snapshotValue)) { if (navigationBase is INavigation navigation) { if (!navigation.ForeignKey.IsOwnership || !navigation.IsOnDependent) { if (_loggingOptions.IsSensitiveDataLoggingEnabled) { _logger.ReferenceChangeDetectedSensitive(entry, navigation, snapshotValue, currentValue); } else { _logger.ReferenceChangeDetected(entry, navigation, snapshotValue, currentValue); } stateManager.InternalEntityEntryNotifier.NavigationReferenceChanged(entry, navigation, snapshotValue, currentValue); } } else { throw new NotImplementedException("TODO: #19003 Non-collection skip navs"); } } }