Beispiel #1
0
        private void DetectKeyChange(InternalEntityEntry entry, IProperty property, Sidecar snapshot)
        {
            if (!snapshot.HasValue(property))
            {
                return;
            }

            var keys        = property.FindContainingKeys().ToList();
            var foreignKeys = property.FindContainingForeignKeys(entry.EntityType).ToList();

            if (keys.Count > 0 ||
                foreignKeys.Count > 0)
            {
                var snapshotValue = snapshot[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, snapshot.GetDependentKeyValue(foreignKey), foreignKey);
                        }
                    }

                    if (keys.Count > 0)
                    {
                        foreach (var key in keys)
                        {
                            stateManager.UpdateIdentityMap(entry, snapshot.GetPrincipalKeyValue(key), key);
                        }

                        stateManager.Notify.PrincipalKeyPropertyChanged(entry, property, snapshotValue, currentValue);
                    }

                    snapshot.TakeSnapshot(property);
                }
            }
        }
        public virtual void SetPropertyModified([NotNull] IProperty property, bool isModified = true)
        {
            // TODO: Restore original value to reject changes when isModified is false
            // Issue #742

            var currentState = _stateData.EntityState;

            if (currentState == EntityState.Added ||
                currentState == EntityState.Detached)
            {
                MarkAsTemporary(property, isTemporary: false);
                OriginalValues.TakeSnapshot(property);
            }

            if ((currentState != EntityState.Modified &&
                 currentState != EntityState.Unchanged)
                // TODO: Consider allowing computed properties to be forcibly marked as modified
                // Issue #711
                || property.IsStoreComputed)
            {
                return;
            }

            if (isModified && property.IsReadOnly)
            {
                throw new NotSupportedException(Strings.PropertyReadOnly(property.Name, EntityType.Name));
            }

            _stateData.FlagProperty(property.Index, isModified);

            // Don't change entity state if it is Added or Deleted
            if (isModified && currentState == EntityState.Unchanged)
            {
                StateManager.Notify.StateChanging(this, EntityState.Modified);
                _stateData.EntityState = EntityState.Modified;
                StateManager.Notify.StateChanged(this, currentState);
            }
            else if (!isModified &&
                     !_stateData.AnyPropertiesFlagged())
            {
                StateManager.Notify.StateChanging(this, EntityState.Unchanged);
                _stateData.EntityState = EntityState.Unchanged;
                StateManager.Notify.StateChanged(this, currentState);
            }
        }
        private void DetectKeyChange(InternalEntityEntry entry, IProperty property, Sidecar snapshot)
        {
            if (!snapshot.HasValue(property))
            {
                return;
            }

            // TODO: Perf: make it fast to check if a property is part of any key
            var isPrimaryKey   = property.IsPrimaryKey();
            var isPrincipalKey = _model.GetReferencingForeignKeys(property).Any();
            var isForeignKey   = property.IsForeignKey();

            if (isPrimaryKey ||
                isPrincipalKey ||
                isForeignKey)
            {
                var snapshotValue = snapshot[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))
                {
                    if (isForeignKey)
                    {
                        entry.StateManager.Notify.ForeignKeyPropertyChanged(entry, property, snapshotValue, currentValue);
                    }

                    if (isPrimaryKey)
                    {
                        entry.StateManager.UpdateIdentityMap(entry, snapshot.GetPrimaryKeyValue());
                    }

                    if (isPrincipalKey)
                    {
                        entry.StateManager.Notify.PrincipalKeyPropertyChanged(entry, property, snapshotValue, currentValue);
                    }

                    snapshot.TakeSnapshot(property);
                }
            }
        }
        public virtual void SetPropertyModified([NotNull] IProperty property, bool isModified = true)
        {
            // TODO: Restore original value to reject changes when isModified is false
            // Issue #742

            var currentState = _stateData.EntityState;

            if (currentState == EntityState.Added ||
                currentState == EntityState.Detached)
            {
                MarkAsTemporary(property, isTemporary: false);
                OriginalValues.TakeSnapshot(property);
            }

            if (currentState != EntityState.Modified &&
                currentState != EntityState.Unchanged)
            {
                return;
            }

            if (isModified && property.IsKey())
            {
                throw new NotSupportedException(CoreStrings.KeyReadOnly(property.Name, EntityType.DisplayName()));
            }

            _stateData.FlagProperty(property.Index, PropertyFlag.TemporaryOrModified, isModified);

            // Don't change entity state if it is Added or Deleted
            if (isModified && currentState == EntityState.Unchanged)
            {
                StateManager.Notify.StateChanging(this, EntityState.Modified);
                _stateData.EntityState = EntityState.Modified;
                StateManager.Notify.StateChanged(this, currentState);
            }
            else if (!isModified &&
                     !_stateData.AnyPropertiesFlagged(PropertyFlag.TemporaryOrModified))
            {
                StateManager.Notify.StateChanging(this, EntityState.Unchanged);
                _stateData.EntityState = EntityState.Unchanged;
                StateManager.Notify.StateChanged(this, currentState);
            }
        }
Beispiel #5
0
        private void DetectNavigationChange(InternalEntityEntry entry, INavigation navigation, Sidecar snapshot)
        {
            var snapshotValue = snapshot[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);

                    snapshot.TakeSnapshot(navigation);
                }
            }
            else if (!ReferenceEquals(currentValue, snapshotValue))
            {
                stateManager.Notify.NavigationReferenceChanged(entry, navigation, snapshotValue, currentValue);

                if (currentValue != null)
                {
                    added.Add(currentValue);
                }

                snapshot.TakeSnapshot(navigation);
            }

            foreach (var addedEntity in added)
            {
                var addedEntry = stateManager.GetOrCreateEntry(addedEntity);
                if (addedEntry.EntityState == EntityState.Detached)
                {
                    _attacher.AttachGraph(addedEntry, EntityState.Added);
                }
            }
        }
        private void DetectNavigationChange(InternalEntityEntry entry, INavigation navigation, Sidecar snapshot)
        {
            var snapshotValue = snapshot[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);

                    snapshot.TakeSnapshot(navigation);
                }
            }
            else if (!ReferenceEquals(currentValue, snapshotValue))
            {
                stateManager.Notify.NavigationReferenceChanged(entry, navigation, snapshotValue, currentValue);

                if (currentValue != null)
                {
                    added.Add(currentValue);
                }

                snapshot.TakeSnapshot(navigation);
            }

            foreach (var addedEntity in added)
            {
                var addedEntry = stateManager.GetOrCreateEntry(addedEntity);
                if (addedEntry.EntityState == EntityState.Detached)
                {
                    _attacher.AttachGraph(addedEntry, EntityState.Added);
                }
            }
        }
        private void DetectKeyChange(InternalEntityEntry entry, IProperty property, Sidecar snapshot)
        {
            if (!snapshot.HasValue(property))
            {
                return;
            }

            var keys = property.FindContainingKeys().ToList();
            var foreignKeys = property.FindContainingForeignKeys(entry.EntityType).ToList();

            if (keys.Count > 0
                || foreignKeys.Count > 0)
            {
                var snapshotValue = snapshot[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, snapshot.GetDependentKeyValue(foreignKey), foreignKey);
                        }
                    }

                    if (keys.Count > 0)
                    {
                        foreach (var key in keys)
                        {
                            stateManager.UpdateIdentityMap(entry, snapshot.GetPrincipalKeyValue(key), key);
                        }

                        stateManager.Notify.PrincipalKeyPropertyChanged(entry, property, snapshotValue, currentValue);
                    }

                    snapshot.TakeSnapshot(property);
                }
            }
        }
        private void DetectKeyChange(InternalEntityEntry entry, IProperty property, Sidecar snapshot)
        {
            if (!snapshot.HasValue(property))
            {
                return;
            }

            // TODO: Perf: make it fast to check if a property is part of any key
            var isPrimaryKey = property.IsPrimaryKey();
            var isPrincipalKey = _model.GetReferencingForeignKeys(property).Any();
            var isForeignKey = property.IsForeignKey();

            if (isPrimaryKey
                || isPrincipalKey
                || isForeignKey)
            {
                var snapshotValue = snapshot[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))
                {
                    if (isForeignKey)
                    {
                        entry.StateManager.Notify.ForeignKeyPropertyChanged(entry, property, snapshotValue, currentValue);
                    }

                    if (isPrimaryKey)
                    {
                        entry.StateManager.UpdateIdentityMap(entry, snapshot.GetPrimaryKeyValue());
                    }

                    if (isPrincipalKey)
                    {
                        entry.StateManager.Notify.PrincipalKeyPropertyChanged(entry, property, snapshotValue, currentValue);
                    }

                    snapshot.TakeSnapshot(property);
                }
            }
        }