private static void DoFixup(IEnumerable <INavigation> navigations, InternalEntityEntry principalEntry, InternalEntityEntry[] dependentEntries) { foreach (var navigation in navigations) { if (navigation.IsDependentToPrincipal()) { var setter = navigation.GetSetter(); foreach (var dependent in dependentEntries) { setter.SetClrValue(dependent.Entity, principalEntry.Entity); dependent.SetRelationshipSnapshotValue(navigation, principalEntry.Entity); } } else { if (navigation.IsCollection()) { var collectionAccessor = navigation.GetCollectionAccessor(); foreach (var dependent in dependentEntries) { var dependentEntity = dependent.Entity; if (!collectionAccessor.Contains(principalEntry.Entity, dependentEntity)) { collectionAccessor.Add(principalEntry.Entity, dependentEntity); principalEntry.AddToCollectionSnapshot(navigation, dependentEntity); } } } else { // TODO: Decide how to handle case where multiple values match non-collection nav prop // Issue #739 var value = dependentEntries.Single().Entity; navigation.GetSetter().SetClrValue(principalEntry.Entity, value); principalEntry.SetRelationshipSnapshotValue(navigation, value); } } } }
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); } } }