/// <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); }
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); }
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); }