Beispiel #1
0
 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();
         }
     }
 }
Beispiel #3
0
        /// <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);
            }
        }