Ejemplo n.º 1
0
        private void DetectKeyChange(InternalEntityEntry entry, IProperty property)
        {
            if (property.GetRelationshipIndex() >= 0)
            {
                var snapshotValue = entry.GetRelationshipSnapshotValue(property);
                var currentValue  = entry[property];

                var comparer = property.GetKeyValueComparer()
                               ?? property.FindTypeMapping()?.KeyComparer;

                // 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 (!(comparer?.Equals(currentValue, snapshotValue)
                      ?? StructuralComparisons.StructuralEqualityComparer.Equals(currentValue, snapshotValue)))
                {
                    var keys        = property.GetContainingKeys().ToList();
                    var foreignKeys = property.GetContainingForeignKeys()
                                      .Where(fk => fk.DeclaringEntityType.IsAssignableFrom(entry.EntityType)).ToList();

                    if (_loggingOptions.IsSensitiveDataLoggingEnabled)
                    {
                        _logger.ForeignKeyChangeDetectedSensitive(entry, property, snapshotValue, currentValue);
                    }
                    else
                    {
                        _logger.ForeignKeyChangeDetected(entry, property, snapshotValue, currentValue);
                    }

                    entry.StateManager.InternalEntityEntryNotifier.KeyPropertyChanged(entry, property, keys, foreignKeys, snapshotValue, currentValue);
                }
            }
        }
Ejemplo n.º 2
0
        private static 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.Any() ||
                    removed.Any())
                {
                    stateManager.InternalEntityEntryNotifier.NavigationCollectionChanged(entry, navigation, added, removed);
                }
            }
            else if (!ReferenceEquals(currentValue, snapshotValue) &&
                     (!navigation.ForeignKey.IsOwnership ||
                      !navigation.IsDependentToPrincipal()))
            {
                stateManager.InternalEntityEntryNotifier.NavigationReferenceChanged(entry, navigation, snapshotValue, currentValue);
            }
        }
Ejemplo n.º 3
0
        private static void DetectKeyChange(InternalEntityEntry entry, IProperty property)
        {
            if (property.GetRelationshipIndex() >= 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 keys        = property.GetContainingKeys().ToList();
                    var foreignKeys = property.GetContainingForeignKeys().ToList();

                    entry.StateManager.Notify.KeyPropertyChanged(entry, property, keys, foreignKeys, snapshotValue, currentValue);
                }
            }
        }
Ejemplo n.º 4
0
        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);
                }
            }
        }
Ejemplo n.º 5
0
        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>(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)
                    {
                        _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.IsOnDependent))
            {
                if (_loggingOptions.IsSensitiveDataLoggingEnabled)
                {
                    _logger.ReferenceChangeDetectedSensitive(entry, navigation, snapshotValue, currentValue);
                }
                else
                {
                    _logger.ReferenceChangeDetected(entry, navigation, snapshotValue, currentValue);
                }

                stateManager.InternalEntityEntryNotifier.NavigationReferenceChanged(entry, navigation, snapshotValue, currentValue);
            }
        }
Ejemplo n.º 6
0
        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))
            {
                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);
            }
        }
Ejemplo n.º 7
0
        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);
                }
            }
        }