/// <summary> /// Build predicate selecting siblings of given element. /// </summary> /// <param name="item">Element to select siblings for. </param> /// <param name="includeSelf">Whether or not to add element itself to result. </param> /// <returns>Predicate selecting siblings of element. </returns> public static TreeFilter SiblingsOf(TreeEntry item, bool includeSelf) { TreeFilter result = r => r.SNv - r.Nv == item.SNv - item.Nv && r.SDv - r.Dv == item.SDv - item.Dv; if (!includeSelf) { result = result.And(r => r.Nv != item.Nv); } return(result); }
/// <summary> /// Add item to hierarchy as next child of given parent item. /// </summary> /// <param name="collection">Entity Framework Collection to add item. </param> /// <param name="parent">Item's parent in hierarchy. </param> /// <param name="item">Element to add to hierarchy. </param> /// <typeparam name="T">Type of elements in collection. Should Implement IHasTreeEntry. </typeparam> /// <returns>Entity Framework EntityEntry object. </returns> public static EntityEntry <T> AddNextChild <T>(this DbSet <T> collection, T parent, T item) where T : class, IHasTreeEntry { TreeEntry parentEntry = null; if (parent != null) { parentEntry = collection.EnsureTreeEntryLoaded(parent); } var lastInterval = GetLastInsertedChildInterval(collection, true, parent); var nextPosition = NestedIntervalMath.GetPositionByInterval(parentEntry, lastInterval) + 1; var treeEntry = new TreeEntry(NestedIntervalMath.GetIntervalByPosition(parentEntry, nextPosition)); item.TreeEntry = treeEntry; var state = collection.Add(item); // state.Reference(i => i.TreeEntry).EntityEntry.State = EntityState.Detached; return(state); }
/// <summary> /// Returns predicate selecting descendants of given element. /// </summary> /// <param name="item">element to select ancestors for. </param> /// <param name="depth">Max inheritance level. </param> /// <param name="includeSelf">Whether or not to add element itself in result. </param> /// <returns>Descendants of element. </returns> public static TreeFilter DescendantsOf(TreeEntry item, int depth, bool includeSelf) { TreeFilter result; if (includeSelf) { result = r => item.Nv * r.Dv <= item.Dv * r.Nv && item.SNv * r.SDv >= item.SDv * r.SNv; } else { result = r => item.Nv * r.Dv <item.Dv *r.Nv && item.SNv *r.SDv> item.SDv * r.SNv; } if (depth > 0) { result = result.And(r => r.Depth - item.Depth <= depth); } return(result); }
/// <summary> /// Build predicate selecting Nth child element of given element. /// </summary> /// <param name="item">Element to select child for. </param> /// <param name="n">Index of child element relative to parent, starting from 1. </param> /// <returns>Predicate selecting siblings positioned before element. </returns> public static TreeFilter NThChildOf(TreeEntry item, int n) { return(r => r.Nv == item.Nv + (item.SNv * n) && r.Dv == item.Dv + (item.SDv * n)); }
/// <summary> /// Build predicate selecting first child element of given element. /// </summary> /// <param name="item">Element to select first child for. </param> /// <returns>Predicate selecting siblings positioned before element. </returns> public static TreeFilter FirstChildOf(TreeEntry item) { return(NThChildOf(item, 1)); }
/// <summary> /// Build predicate selecting sibling element positioned next to tree entry of given element. /// </summary> /// <param name="item">Element to select next sibling for. </param> /// <returns>Predicate selecting next siblings of element. </returns> public static TreeFilter NextSiblingOf(TreeEntry item) { return(r => r.Nv == item.SNv && r.Dv == item.SDv); }
/// <summary> /// Build predicate selecting siblings positioned after given element. /// </summary> /// <param name="item">Element to select siblings for. </param> /// <param name="includeSelf">Whether or not to add element itself to result. </param> /// <returns>Predicate selecting siblings positioned after element. </returns> public static TreeFilter SiblingsAfter(TreeEntry item, bool includeSelf) { return(SiblingsOf(item, includeSelf).And(r => r.Nv >= item.Nv)); }