private async Task SaveChanges(bool showToast) { await _repository .SaveAsync(_trackingCollection.GetChanges(), DisposeCancellationToken) .WithBusyIndicator(this, UiResources.SaveBusyMessage); _trackingCollection.SetStateForAll(entity => entity.State.IsDeleted(), EntityState.Detached); _trackingCollection.SetStateForAll(entity => !entity.State.IsDeleted(), EntityState.Unchanged); this.OnPropertyChanged(() => v => v.HasChanges); if (showToast) { _toastPresenter.ShowAsync(UiResources.SaveToastMessage, ToastDuration.Long); } }
/// <summary> /// Restore items marked as deleted. /// </summary> /// <param name="changeTracker">Change-tracking collection</param> /// <param name="visitationHelper">Circular reference checking helper</param> public static void RestoreDeletes(this ITrackingCollection changeTracker, ObjectVisitationHelper visitationHelper = null) { ObjectVisitationHelper.EnsureCreated(ref visitationHelper); // Get cached deletes var removedDeletes = changeTracker.GetChanges(true).Cast <ITrackable>().ToList(); // Restore deleted items if (removedDeletes.Any()) { var isTracking = changeTracker.Tracking; changeTracker.Tracking = false; foreach (var delete in removedDeletes) { var items = changeTracker as IList; if (items != null && !items.Contains(delete)) { items.Add(delete); } } changeTracker.Tracking = isTracking; } foreach (var item in changeTracker.Cast <ITrackable>()) { // Prevent endless recursion if (!visitationHelper.TryVisit(item)) { continue; } // Iterate entity properties foreach (var navProp in item.GetNavigationProperties()) { // Process 1-1 and M-1 properties foreach (var refProp in navProp.AsReferenceProperty()) { // Get changed ref prop ITrackingCollection refChangeTracker = item.GetRefPropertyChangeTracker(refProp.Property.Name); // Restore deletes on rep prop if (refChangeTracker != null) { refChangeTracker.RestoreDeletes(visitationHelper); } } // Process 1-M and M-M properties foreach (var colProp in navProp.AsCollectionProperty <ITrackingCollection>()) { colProp.EntityCollection.RestoreDeletes(visitationHelper); } } } }
public async void LoadState(IDataContext state) { ITrackingCollection trackingCollection = state.GetData(StateConstant); if (trackingCollection == null) { return; } IList <IEntityStateEntry> changes = trackingCollection.GetChanges(); await _initializedTask; _trackingCollection.UpdateStates(changes); foreach (IEntityStateEntry change in changes) { var oldItem = (ProductModel)change.Entity; ProductModel currentItem = GridViewModel.OriginalItemsSource.FirstOrDefault(model => model.Id == oldItem.Id); switch (change.State) { case EntityState.Added: GridViewModel.OriginalItemsSource.Add(oldItem); break; case EntityState.Modified: if (currentItem != null) { GridViewModel.OriginalItemsSource.Remove(currentItem); } GridViewModel.OriginalItemsSource.Add(oldItem); break; case EntityState.Deleted: if (currentItem != null) { GridViewModel.OriginalItemsSource.Remove(currentItem); } break; } } this.OnPropertyChanged(() => v => v.HasChanges); }
/// <summary> /// Recursively remove items marked as deleted. /// </summary> /// <param name="changeTracker">Change-tracking collection</param> /// <param name="visitationHelper">Circular reference checking helper</param> public static void RemoveRestoredDeletes(this ITrackingCollection changeTracker, ObjectVisitationHelper visitationHelper = null) { ObjectVisitationHelper.EnsureCreated(ref visitationHelper); // Iterate items in change-tracking collection var items = changeTracker as IList; if (items == null) { return; } var count = items.Count; for (int i = count - 1; i > -1; i--) { // Get trackable item var item = items[i] as ITrackable; if (item == null) { continue; } // Prevent endless recursion if (!visitationHelper.TryVisit(item)) { continue; } // Iterate entity properties foreach (var navProp in item.GetNavigationProperties()) { // Process 1-1 and M-1 properties foreach (var refProp in navProp.AsReferenceProperty()) { // Get changed ref prop ITrackingCollection refChangeTracker = item.GetRefPropertyChangeTracker(refProp.Property.Name); // Remove deletes on rep prop if (refChangeTracker != null) { refChangeTracker.RemoveRestoredDeletes(visitationHelper); } } // Process 1-M and M-M properties foreach (var colProp in navProp.AsCollectionProperty <ITrackingCollection>()) { colProp.EntityCollection.RemoveRestoredDeletes(visitationHelper); } } // Remove item if marked as deleted var removedDeletes = changeTracker.GetChanges(true).Cast <ITrackable>().ToList(); if (item.TrackingState == TrackingState.Deleted) { var isTracking = changeTracker.Tracking; changeTracker.Tracking = false; if (removedDeletes.Contains(item)) { items.Remove(item); } changeTracker.Tracking = isTracking; } } }