private static void Unfixup(INavigation navigation, InternalEntityEntry oldPrincipalEntry, InternalEntityEntry dependentEntry) { var dependentEntity = dependentEntry.Entity; if (navigation.IsDependentToPrincipal()) { navigation.GetSetter().SetClrValue(dependentEntity, null); dependentEntry.SetRelationshipSnapshotValue(navigation, null); } else { if (navigation.IsCollection()) { var collectionAccessor = navigation.GetCollectionAccessor(); if (collectionAccessor.Contains(oldPrincipalEntry.Entity, dependentEntity)) { collectionAccessor.Remove(oldPrincipalEntry.Entity, dependentEntity); oldPrincipalEntry.RemoveFromCollectionSnapshot(navigation, dependentEntity); } } else { navigation.GetSetter().SetClrValue(oldPrincipalEntry.Entity, null); oldPrincipalEntry.SetRelationshipSnapshotValue(navigation, null); } } }
private static void SetNullForeignKey(InternalEntityEntry dependentEntry, IReadOnlyList <IProperty> dependentProperties) { foreach (var dependentProperty in dependentProperties) { dependentEntry[dependentProperty] = null; dependentEntry.SetRelationshipSnapshotValue(dependentProperty, null); } }
private static void SetForeignKeyValue(IForeignKey foreignKey, InternalEntityEntry dependentEntry, IReadOnlyList <object> principalValues) { for (var i = 0; i < foreignKey.Properties.Count; i++) { var principalValue = principalValues[i]; if ((foreignKey.Properties[i].GetGenerationProperty() == null) || !foreignKey.PrincipalKey.Properties[i].ClrType.IsDefaultValue(principalValue)) { var dependentProperty = foreignKey.Properties[i]; dependentEntry[dependentProperty] = principalValue; dependentEntry.SetRelationshipSnapshotValue(dependentProperty, principalValue); } } }
private static void StealReference(IForeignKey foreignKey, InternalEntityEntry dependentEntry) { var navigation = foreignKey.DependentToPrincipal; if (navigation != null) { navigation.GetSetter().SetClrValue(dependentEntry.Entity, null); dependentEntry.SetRelationshipSnapshotValue(navigation, null); } foreach (var property in foreignKey.Properties.Where(p => p.IsNullable).ToList()) { dependentEntry[property] = null; } }
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 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; 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); } } }