public virtual async Task <IEnumerable <string> > PushAsync(IPropertyChangeTracker tracker, IDataAccessLayer dal, int action, int commentId) { InvokeBeforePushActions(); long utcTimestamp = DateTime.UtcNow.Ticks; IsPushing = true; RaisePushing(); IEnumerable <string> changes = DbEntityChanges(tracker, utcTimestamp); try { int editDuration = (int)Math.Round(EditDuration); IDictionary <string, Tuple <string, object>[]> newEntitiesPrimaryKeys = await dal.UpdateEntity(GetType(), ChangesAsJson(tracker, utcTimestamp), changes, action, editDuration, commentId); tracker.Untracked((e) => { DbEntityUtilities.UpdatePrimaryKeys(newEntitiesPrimaryKeys, this); }); // TODO: Only clear the changes if the push has been successful PurgeChanges(tracker, utcTimestamp); RaisePushed(changes); } catch (Exception) { changes = Enumerable.Empty <string>(); } finally { IsPushing = false; } return(changes); }
public bool Contains(TEntity entity) { bool contains = false; if (entity.State == EntityState.New) { contains = Collection.Any(e => !e.IsDeleted && e.Guid.Equals(entity.Guid)); } else { contains = Collection.Any(e => !e.IsDeleted && DbEntityUtilities.PrimaryKeysEqual(e.PrimaryKeys, entity.PrimaryKeys)); } return(contains); }
private void ProcessCollectionChange(NotifyCollectionChangedAction action, IEnumerable items, string path, string propertyName, IDbEntity parentEntity) { if (!_isCreatingHandlers && IsValid(parentEntity.GetType(), path, propertyName)) { if (action == NotifyCollectionChangedAction.Add) { ICollection <PropertyChange> changes = new List <PropertyChange>(); foreach (IDbEntity navigationEntity in items.Cast <IDbEntity>()) { string entityPath = DbEntityUtilities.GenerateCollectionItemPath(path + propertyName, navigationEntity.Guid); PropertyChange change = new PropertyChange(entityPath, string.Empty, navigationEntity.Guid, null, navigationEntity, true, navigationEntity.State); if (_entity.IsTrackingChanges) { changes.Add(change); MergeChanges(navigationEntity, entityPath, !_entity.IsTrackingChanges); } CreateHandlers(navigationEntity, entityPath); } if (_entity.IsTrackingChanges) { AddChanges(changes); } Validate(null, true); } else if (action == NotifyCollectionChangedAction.Remove) { ICollection <PropertyChange> changes = new List <PropertyChange>(); string propertyPath = DbEntityUtilities.GeneratePropertyPath(path, propertyName); foreach (IDbEntity removedEntity in items.Cast <IDbEntity>()) { string entityPath = DbEntityUtilities.GenerateCollectionItemPath(propertyPath, removedEntity.Guid); PropertyChange change = new PropertyChange(entityPath, string.Empty, removedEntity.Guid, removedEntity, null, true, removedEntity.State); if (_entity.IsTrackingChanges) { changes.Add(change); } RemoveHandlers(removedEntity, entityPath); Validate(change, true); } if (_entity.IsTrackingChanges) { AddChanges(changes); } changes.Clear(); } } }
private void RevertCollectionChange <T>(IEnumerable entities) where T : class, IDbEntity { ICollection <T> collection = entities as ICollection <T>; if (Before == null && After != null && DbEntityUtilities.IsIDbEntity(After.GetType())) { // This property change refers to a newly added entity to this collection. To revert it, remove the added entity from the collection collection.Remove(After as T); } else if (Before != null && DbEntityUtilities.IsIDbEntity(Before.GetType()) && After == null && !collection.Contains(Before as T)) { // This property change refers to an entity removed from this collection. To revert it, re-add the removed entity to the collection collection.Add(Before as T); } }
private void ApplyCollectionChange <T>(IEnumerable entities) where T : class, IDbEntity { // If remove (i.e. before = typeof(IDbEntity), after = null), remove before value ICollection <T> collection = entities as ICollection <T>; if (Before == null && After != null && DbEntityUtilities.IsIDbEntity(After.GetType()) && !collection.Contains(After as T)) { // This property change refers to a newly added entity to this collection. To re-apply it, re-add the added entity to the collection collection.Add(After as T); } else if (Before != null && DbEntityUtilities.IsIDbEntity(Before.GetType()) && After == null) { // This property change refers to an entity removed from this collection. To re-apply it, remove the removed entity from the collection collection.Remove(Before as T); } }
private ISet <string> GetChangePathsPrefixes(IDbEntity root) { ISet <string> changePathsPrefixes = new HashSet <string>() { "." }; if (root != null) { ISet <string> entitiesPaths; if (_entitiesPaths.TryGetValue(root.Guid, out entitiesPaths)) { changePathsPrefixes.Clear(); foreach (string prefix in entitiesPaths) { changePathsPrefixes.Add(DbEntityUtilities.GetDbEntityPropertyPath(prefix, _entity)); changePathsPrefixes.Add(prefix); } } } return(changePathsPrefixes); }
public TEntity Get(Tuple <string, object>[] primaryKeys) { return(Collection.SingleOrDefault(e => /*!e.IsDeleted && */ DbEntityUtilities.PrimaryKeysEqual(e.PrimaryKeys, primaryKeys))); }
public string DbEntityPropertyPath(IDbEntity entity) { return(DbEntityUtilities.GetDbEntityPropertyPath(PropertyPath, entity)); }
private void EntityPropertyChanged(object sender, DbEntityPropertyChangedEventArgs e, string path) { IDbEntity entity = sender as IDbEntity; PropertyChange change = null; // Save a reference to the property changed if (!_isCreatingHandlers && IsValid(sender.GetType(), path, e.PropertyName) && (!e.PropertyName.Equals("IsDeleted") || entity.State == EntityState.Persisted)) { string propertyPath = path + e.PropertyName; PropertyInfo p = entity.GetType().GetProperty(e.PropertyName); bool isEnumerable = p.GetGetMethod().ReturnType.IsIEnumerable(); bool isDbEntityEnumerable = false; bool isIDbEntity = DbEntityUtilities.IsIDbEntity(p); if (isIDbEntity) { propertyPath = propertyPath + "."; if (e.Before != null) { RemoveHandlers(e.Before as IDbEntity, propertyPath); } if (e.After != null) { // Defer any changes tracking that might have been recorded on the navigation entity to the root entity IDbEntity navigationEntity = e.After as IDbEntity; if (_entity.IsTrackingChanges) { MergeChanges(navigationEntity, propertyPath, !_entity.IsTrackingChanges); } CreateHandlers(navigationEntity, propertyPath); } } else if ((isEnumerable && p.GetGetMethod().ReturnType.GetGenericArguments().Count() > 0 && DbEntityUtilities.IsIDbEntity(p.GetGetMethod().ReturnType.GetGenericArguments()[0]))) { isDbEntityEnumerable = true; if (e.Before != null) { RemoveCollectionHandlers(entity, e.Before as IEnumerable <IDbEntity>, path, propertyPath + ".", p); } if (e.After != null) { foreach (IDbEntity navigationEntity in e.After as IEnumerable <IDbEntity> ) { if (navigationEntity != null) { string entityPath = DbEntityUtilities.GenerateCollectionItemPath(propertyPath, navigationEntity.Guid); if (_entity.IsTrackingChanges) { MergeChanges(navigationEntity, entityPath, !_entity.IsTrackingChanges); } CreateHandlers(navigationEntity, entityPath); } } } } if (_entity.IsTrackingChanges) { change = new PropertyChange(path, e.PropertyName, entity.Guid, e.Before, e.After, entity.State); if (isDbEntityEnumerable) { change = new PropertyChange(path, e.PropertyName, entity.Guid, e.Before, e.After); } PurgeLast(p.GetGetMethod().ReturnType, change); AddChange(change); Validate(change, isIDbEntity); } //_logTo.DebugQueue(new EntityPropertyChangedLogEntry(SettingsModel.Current.User.id, entity.PrimaryKeys, entity.GetType(), propertyPath)); } }