示例#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 virtual bool SnapshotAndSubscribe(InternalEntityEntry entry)
        {
            var entityType = entry.EntityType;

            if (entityType.UseEagerSnapshots())
            {
                entry.EnsureOriginalValues();
                entry.EnsureRelationshipSnapshot();
            }

            var changeTrackingStrategy = entityType.GetChangeTrackingStrategy();

            if (changeTrackingStrategy == ChangeTrackingStrategy.Snapshot)
            {
                return(false);
            }

            foreach (var navigation in entityType.GetNavigations().Where(n => n.IsCollection()))
            {
                AsINotifyCollectionChanged(entry, navigation, entityType, changeTrackingStrategy).CollectionChanged
                    += entry.HandleINotifyCollectionChanged;
            }

            if (changeTrackingStrategy != ChangeTrackingStrategy.ChangedNotifications)
            {
                AsINotifyPropertyChanging(entry, entityType, changeTrackingStrategy).PropertyChanging
                    += entry.HandleINotifyPropertyChanging;
            }

            AsINotifyPropertyChanged(entry, entityType, changeTrackingStrategy).PropertyChanged
                += entry.HandleINotifyPropertyChanged;

            return(true);
        }
示例#2
0
        public virtual void PropertyChanging(InternalEntityEntry entry, IPropertyBase propertyBase)
        {
            if (_suspended)
            {
                return;
            }

            if (!entry.EntityType.UseEagerSnapshots())
            {
                entry.EnsureOriginalValues();

                if (propertyBase.GetRelationshipIndex() != -1)
                {
                    entry.EnsureRelationshipSnapshot();
                }
            }
        }
        public virtual InternalEntityEntry SnapshotAndSubscribe(InternalEntityEntry entry)
        {
            var entityType = entry.EntityType;

            if (entityType.UseEagerSnapshots())
            {
                entry.EnsureOriginalValues();
                entry.EnsureRelationshipSnapshot();
            }
            else if (entityType.GetNavigations().Any(n => n.IsNonNotifyingCollection(entry)))
            {
                entry.EnsureRelationshipSnapshot();
            }

            var changing = entry.Entity as INotifyPropertyChanging;

            if (changing != null)
            {
                changing.PropertyChanging += (s, e) =>
                {
                    var property = TryGetPropertyBase(entityType, e.PropertyName);
                    if (property != null)
                    {
                        _notifier.PropertyChanging(entry, property);
                    }
                };
            }

            var changed = entry.Entity as INotifyPropertyChanged;

            if (changed != null)
            {
                changed.PropertyChanged += (s, e) =>
                {
                    var property = TryGetPropertyBase(entityType, e.PropertyName);
                    if (property != null)
                    {
                        _notifier.PropertyChanged(entry, property);
                    }
                };
            }

            return(entry);
        }
示例#4
0
        public virtual void PropertyChanging(InternalEntityEntry entry, IPropertyBase propertyBase)
        {
            if (_suspended || entry.EntityState == EntityState.Detached)
            {
                return;
            }

            if (!entry.EntityType.UseEagerSnapshots())
            {
                var asProperty = propertyBase as IProperty;
                if (asProperty != null &&
                    asProperty.GetOriginalValueIndex() != -1)
                {
                    entry.EnsureOriginalValues();
                }

                if (propertyBase.GetRelationshipIndex() != -1)
                {
                    entry.EnsureRelationshipSnapshot();
                }
            }
        }
        public virtual InternalEntityEntry SnapshotAndSubscribe(InternalEntityEntry entry)
        {
            var entityType = entry.EntityType;

            if (entityType.UseEagerSnapshots())
            {
                entry.EnsureOriginalValues();
                entry.EnsureRelationshipSnapshot();
            }

            var changeTrackingStrategy = entityType.GetChangeTrackingStrategy();

            if (changeTrackingStrategy != ChangeTrackingStrategy.Snapshot)
            {
                foreach (var navigation in entityType.GetNavigations().Where(n => n.IsCollection()))
                {
                    var notifyingCollection = navigation.GetCollectionAccessor().GetOrCreate(entry.Entity) as INotifyCollectionChanged;
                    if (notifyingCollection == null)
                    {
                        throw new InvalidOperationException(
                                  CoreStrings.NonNotifyingCollection(navigation.Name, entityType.DisplayName(), changeTrackingStrategy));
                    }

                    notifyingCollection.CollectionChanged += (s, e) =>
                    {
                        switch (e.Action)
                        {
                        case NotifyCollectionChangedAction.Add:
                            _notifier.NavigationCollectionChanged(
                                entry,
                                navigation,
                                e.NewItems.OfType <object>(),
                                Enumerable.Empty <object>());
                            break;

                        case NotifyCollectionChangedAction.Remove:
                            _notifier.NavigationCollectionChanged(
                                entry,
                                navigation,
                                Enumerable.Empty <object>(),
                                e.OldItems.OfType <object>());
                            break;

                        case NotifyCollectionChangedAction.Replace:
                            _notifier.NavigationCollectionChanged(
                                entry,
                                navigation,
                                e.NewItems.OfType <object>(),
                                e.OldItems.OfType <object>());
                            break;

                        case NotifyCollectionChangedAction.Reset:
                            if (e.OldItems == null)
                            {
                                throw new InvalidOperationException(CoreStrings.ResetNotSupported);
                            }

                            _notifier.NavigationCollectionChanged(
                                entry,
                                navigation,
                                Enumerable.Empty <object>(),
                                e.OldItems.OfType <object>());
                            break;
                            // Note: ignoring Move since index not important
                        }
                    };
                }

                if (changeTrackingStrategy != ChangeTrackingStrategy.ChangedNotifications)
                {
                    var changing = entry.Entity as INotifyPropertyChanging;
                    if (changing == null)
                    {
                        throw new InvalidOperationException(
                                  CoreStrings.ChangeTrackingInterfaceMissing(
                                      entityType.DisplayName(), changeTrackingStrategy, typeof(INotifyPropertyChanging).Name));
                    }

                    changing.PropertyChanging += (s, e) =>
                    {
                        foreach (var propertyBase in GetNotificationProperties(entityType, e.PropertyName))
                        {
                            _notifier.PropertyChanging(entry, propertyBase);
                        }
                    };
                }

                var changed = entry.Entity as INotifyPropertyChanged;
                if (changed == null)
                {
                    throw new InvalidOperationException(
                              CoreStrings.ChangeTrackingInterfaceMissing(
                                  entityType.DisplayName(), changeTrackingStrategy, typeof(INotifyPropertyChanged).Name));
                }

                changed.PropertyChanged += (s, e) =>
                {
                    foreach (var propertyBase in GetNotificationProperties(entityType, e.PropertyName))
                    {
                        _notifier.PropertyChanged(entry, propertyBase, setModified: true);
                    }
                };
            }

            return(entry);
        }