private void DetectKeyChange(InternalEntityEntry entry, IProperty property) { if (property.GetRelationshipIndex() >= 0) { var snapshotValue = entry.GetRelationshipSnapshotValue(property); var currentValue = entry[property]; var comparer = property.GetKeyValueComparer() ?? property.FindTypeMapping()?.KeyComparer; // Note that mutation of a byte[] key is not supported or detected, but two different instances // of byte[] with the same content must be detected as equal. if (!(comparer?.Equals(currentValue, snapshotValue) ?? StructuralComparisons.StructuralEqualityComparer.Equals(currentValue, snapshotValue))) { var keys = property.GetContainingKeys().ToList(); var foreignKeys = property.GetContainingForeignKeys() .Where(fk => fk.DeclaringEntityType.IsAssignableFrom(entry.EntityType)).ToList(); if (_loggingOptions.IsSensitiveDataLoggingEnabled) { _logger.ForeignKeyChangeDetectedSensitive(entry, property, snapshotValue, currentValue); } else { _logger.ForeignKeyChangeDetected(entry, property, snapshotValue, currentValue); } entry.StateManager.InternalEntityEntryNotifier.KeyPropertyChanged(entry, property, keys, foreignKeys, snapshotValue, currentValue); } } }
private static 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.Any() || removed.Any()) { stateManager.InternalEntityEntryNotifier.NavigationCollectionChanged(entry, navigation, added, removed); } } else if (!ReferenceEquals(currentValue, snapshotValue) && (!navigation.ForeignKey.IsOwnership || !navigation.IsDependentToPrincipal())) { stateManager.InternalEntityEntryNotifier.NavigationReferenceChanged(entry, navigation, snapshotValue, currentValue); } }
private static void DetectKeyChange(InternalEntityEntry entry, IProperty property) { if (property.GetRelationshipIndex() >= 0) { var snapshotValue = entry.GetRelationshipSnapshotValue(property); var currentValue = entry[property]; // Note that mutation of a byte[] key is not supported or detected, but two different instances // of byte[] with the same content must be detected as equal. if (!StructuralComparisons.StructuralEqualityComparer.Equals(currentValue, snapshotValue)) { var keys = property.GetContainingKeys().ToList(); var foreignKeys = property.GetContainingForeignKeys().ToList(); entry.StateManager.Notify.KeyPropertyChanged(entry, property, keys, foreignKeys, snapshotValue, currentValue); } } }
private static void DetectKeyChange(InternalEntityEntry entry, IProperty property) { var keys = property.FindContainingKeys().ToList(); var foreignKeys = property.FindContainingForeignKeys().ToList(); if ((keys.Count > 0) || (foreignKeys.Count > 0)) { var snapshotValue = entry.GetRelationshipSnapshotValue(property); var currentValue = entry[property]; // Note that mutation of a byte[] key is not supported or detected, but two different instances // of byte[] with the same content must be detected as equal. if (!StructuralComparisons.StructuralEqualityComparer.Equals(currentValue, snapshotValue)) { var stateManager = entry.StateManager; if (foreignKeys.Count > 0) { stateManager.Notify.ForeignKeyPropertyChanged(entry, property, snapshotValue, currentValue); foreach (var foreignKey in foreignKeys) { stateManager.UpdateDependentMap(entry, foreignKey); } } if (keys.Count > 0) { foreach (var key in keys) { stateManager.UpdateIdentityMap(entry, key); } stateManager.Notify.PrincipalKeyPropertyChanged(entry, property, snapshotValue, currentValue); } entry.SetRelationshipSnapshotValue(property, 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>(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) { _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.IsOnDependent)) { 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)) { 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; var added = new HashSet <object>(ReferenceEqualityComparer.Instance); 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); } } if (currentCollection != null) { foreach (var entity in currentCollection) { if (!removed.Remove(entity)) { added.Add(entity); } } } if (added.Any() || removed.Any()) { stateManager.Notify.NavigationCollectionChanged(entry, navigation, added, removed); foreach (var addedEntity in added) { entry.AddToCollectionSnapshot(navigation, addedEntity); } foreach (var removedEntity in removed) { entry.RemoveFromCollectionSnapshot(navigation, removedEntity); } } } else if (!ReferenceEquals(currentValue, snapshotValue)) { stateManager.Notify.NavigationReferenceChanged(entry, navigation, snapshotValue, currentValue); if (currentValue != null) { added.Add(currentValue); } entry.SetRelationshipSnapshotValue(navigation, currentValue); } foreach (var addedEntity in added) { var addedEntry = stateManager.GetOrCreateEntry(addedEntity); if (addedEntry.EntityState == EntityState.Detached) { _attacher.AttachGraph(addedEntry, EntityState.Added); } } }