private void AddToCollection(InternalEntityEntry entry, INavigation navigation, InternalEntityEntry value) { if (navigation != null) { _changeDetector.Suspend(); try { if (entry.AddToCollection(navigation, value)) { entry.AddToCollectionSnapshot(navigation, value.Entity); } } finally { _changeDetector.Resume(); } } }
private void AddToCollection( InternalEntityEntry entry, INavigation navigation, IClrCollectionAccessor collectionAccessor, object value) { if (navigation != null) { _changeDetector.Suspend(); try { if (collectionAccessor.Add(entry.Entity, value)) { entry.AddToCollectionSnapshot(navigation, value); } } finally { _changeDetector.Resume(); } } }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public virtual void NavigationCollectionChanged( InternalEntityEntry entry, INavigation navigation, IEnumerable <object> added, IEnumerable <object> removed) { if (_inFixup) { return; } var foreignKey = navigation.ForeignKey; var stateManager = entry.StateManager; var inverse = navigation.FindInverse(); var targetEntityType = navigation.GetTargetType(); foreach (var oldValue in removed) { var oldTargetEntry = stateManager.TryGetEntry(oldValue, targetEntityType); if (oldTargetEntry != null && oldTargetEntry.EntityState != EntityState.Detached) { try { _inFixup = true; // Null FKs and navigations of dependents that have been removed, unless they // have already been changed. ConditionallyNullForeignKeyProperties(oldTargetEntry, entry, foreignKey); if (inverse != null && ReferenceEquals(oldTargetEntry[inverse], entry.Entity) && oldTargetEntry.StateManager.TryGetEntry(oldTargetEntry.Entity, targetEntityType) != null) { SetNavigation(oldTargetEntry, inverse, null); } entry.RemoveFromCollectionSnapshot(navigation, oldValue); } finally { _inFixup = false; } } } foreach (var newValue in added) { var newTargetEntry = targetEntityType.HasDefiningNavigation() ? stateManager.GetOrCreateEntry(newValue, targetEntityType) : stateManager.GetOrCreateEntry(newValue); if (newTargetEntry.EntityState != EntityState.Detached) { try { _inFixup = true; // For a dependent added to the collection, remove it from the collection of // the principal entity that it was previously part of var oldPrincipalEntry = stateManager.GetPrincipalUsingRelationshipSnapshot(newTargetEntry, foreignKey); if (oldPrincipalEntry != null && oldPrincipalEntry != entry) { RemoveFromCollection(oldPrincipalEntry, navigation, newTargetEntry); } // Set the FK properties on added dependents to match this principal SetForeignKeyProperties(newTargetEntry, entry, foreignKey, setModified: true); // Set the inverse navigation to point to this principal SetNavigation(newTargetEntry, inverse, entry); } finally { _inFixup = false; } } else { stateManager.RecordReferencedUntrackedEntity(newValue, navigation, entry); _attacher.AttachGraph(newTargetEntry, EntityState.Added, forceStateWhenUnknownKey: false); } entry.AddToCollectionSnapshot(navigation, newValue); } }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public virtual void NavigationCollectionChanged( InternalEntityEntry entry, INavigation navigation, IEnumerable<object> added, IEnumerable<object> removed) { if (_inFixup) { return; } var foreignKey = navigation.ForeignKey; var stateManager = entry.StateManager; var inverse = navigation.FindInverse(); var collectionAccessor = navigation.GetCollectionAccessor(); foreach (var oldValue in removed) { var oldTargetEntry = stateManager.TryGetEntry(oldValue); if (oldTargetEntry != null && oldTargetEntry.EntityState != EntityState.Detached) { try { _inFixup = true; // Null FKs and navigations of dependents that have been removed, unless they // have already been changed. ConditionallyNullForeignKeyProperties(oldTargetEntry, entry, foreignKey); if (inverse != null && ReferenceEquals(oldTargetEntry[inverse], entry.Entity)) { SetNavigation(oldTargetEntry, inverse, null); } entry.RemoveFromCollectionSnapshot(navigation, oldValue); } finally { _inFixup = false; } } } foreach (var newValue in added) { var newTargetEntry = stateManager.GetOrCreateEntry(newValue); if (newTargetEntry.EntityState != EntityState.Detached) { try { _inFixup = true; // For a dependent added to the collection, remove it from the collection of // the principal entity that it was previously part of var oldPrincipalEntry = stateManager.GetPrincipal(newTargetEntry, foreignKey); if (oldPrincipalEntry != null) { RemoveFromCollection(oldPrincipalEntry, navigation, collectionAccessor, newValue); } // Set the FK properties on added dependents to match this principal SetForeignKeyProperties(newTargetEntry, entry, foreignKey, setModified: true); // Set the inverse navigation to point to this principal SetNavigation(newTargetEntry, inverse, entry.Entity); } finally { _inFixup = false; } } else { stateManager.RecordReferencedUntrackedEntity(newValue, navigation, entry); _attacher.AttachGraph(newTargetEntry, EntityState.Added); } entry.AddToCollectionSnapshot(navigation, newValue); } }