Exemple #1
0
    /// <summary>
    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
    ///     any release. You should only use it directly in your code with extreme caution and knowing that
    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
    /// </summary>
    public 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;

            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.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.IsDependentToPrincipal()))
            {
                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))
            {
                if (navigationBase is INavigation navigation)
                {
                    if (!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);
                    }
                }
                else
                {
                    throw new NotImplementedException("TODO: #19003 Non-collection skip navs");
                }
            }
        }