private void Move(TKey nodeId, TNullableKey toParentId, TNullableKey toSiblingId, NestedSetInsertMode insertMode) { //var node = _nodes.Single(KeyEqualsExpression(nodeId)); var deletedNodes = Delete(nodeId); Insert(toParentId, toSiblingId, deletedNodes, insertMode); }
private List <T> Insert(TNullableKey parentId, TNullableKey siblingId, IEnumerable <T> nodeTree, NestedSetInsertMode insertMode) { var nodeArray = nodeTree as T[] ?? nodeTree.ToArray(); var lowestLeft = nodeArray.Min(n => n.Left); var highestRight = nodeArray.Max(n => n.Right); if (lowestLeft == 0 && highestRight == 0) { if (nodeArray.Length == 1) { var node = nodeArray.Single(); node.Left = 1; node.Right = 2; lowestLeft = 1; highestRight = 2; } else { throw new ArgumentException("Node tree must have left right values", nameof(nodeTree)); } } var difference = highestRight - lowestLeft; var nodeTreeRoot = nodeArray.Single(n => n.Left == lowestLeft); T parent = null; T sibling = null; var isRoot = Equals(parentId, default(TNullableKey)) && Equals(siblingId, default(TNullableKey)); if (!Equals(parentId, default(TNullableKey)) && insertMode == NestedSetInsertMode.Right) { parent = GetNode(parentId); if (parent == null) { throw new ArgumentException(string.Format("Unable to find node parent with ID of {0}", parentId)); } var parent1 = parent; var rightMostImmediateChild = GetNodes(parent.RootId) .Where(s => s.Left >= parent1.Left && s.Right <= parent1.Right && s.Level == parent1.Level + 1) .OrderByDescending(s => s.Right) .ToList() .FirstOrDefault(n => !n.Moving) ; sibling = rightMostImmediateChild; if (sibling != null) { siblingId = (TNullableKey)(object)sibling.Id; } } int?siblingLeft = null; int?siblingRight = null; var rootId = default(TNullableKey); if (!Equals(siblingId, default(TNullableKey))) { if (sibling == null) { sibling = GetNode(siblingId); } siblingLeft = sibling.Left; siblingRight = sibling.Right; parentId = sibling.ParentId; rootId = sibling.RootId; } int?parentLeft = null; if (!Equals(parentId, default(TNullableKey))) { if (parent == null) { parent = GetNode(parentId); } parentLeft = parent.Left; rootId = parent.RootId; } var minLevel = nodeArray.Min(n => n.Level); foreach (var node in nodeArray) { node.Level -= minLevel; if (parent != null) { node.Level += parent.Level + 1; } } var left = 0; var right = 0; switch (insertMode) { case NestedSetInsertMode.Left: { IEnumerable <T> nodes; if (sibling != null) { nodes = GetNodes(rootId) .Where(s => s.Left >= siblingLeft || s.Right >= siblingRight).ToList() .Where(n => !n.Moving) .ToList(); left = sibling.Left; right = sibling.Left + difference; foreach (var nodeToUpdate in nodes) { if (nodeToUpdate.Left >= siblingLeft) { nodeToUpdate.Left += difference + 1; } nodeToUpdate.Right += difference + 1; } } else if (parent != null) { nodes = GetNodes(rootId).Where(s => s.Right >= parentLeft).ToList() .Where(n => !n.Moving) .ToList(); left = parent.Left + 1; right = left + difference; foreach (var nodeToUpdate in nodes) { if (nodeToUpdate.Left > parentLeft) { nodeToUpdate.Left += difference + 1; } nodeToUpdate.Right += difference + 1; } } else { left = 1; right = 1 + difference; } } break; case NestedSetInsertMode.Right: { List <T> nodes; if (sibling != null) { nodes = GetNodes(rootId) .Where(s => s.Left > siblingRight || s.Right > siblingRight) .ToList() .Where(n => !n.Moving) .ToList(); left = sibling.Right + 1; right = sibling.Right + 1 + difference; foreach (var nodeToUpdate in nodes) { if (nodeToUpdate.Left > siblingLeft) { nodeToUpdate.Left += difference + 1; } nodeToUpdate.Right += difference + 1; } } else if (parent != null) { nodes = GetNodes(rootId) .Where(s => s.Right >= parentLeft).ToList() .Where(n => !n.Moving) .ToList(); left = parent.Left + 1; right = left + difference; foreach (var nodeToUpdate in nodes) { if (nodeToUpdate.Left > parentLeft) { nodeToUpdate.Left += difference + 1; } nodeToUpdate.Right += difference + 1; } } else { left = 1; right = 1 + difference; } } break; } var leftChange = left - nodeTreeRoot.Left; var rightChange = right - nodeTreeRoot.Right; foreach (var node in nodeArray) { node.Left += leftChange; node.Right += rightChange; } nodeTreeRoot.ParentId = parentId; var newNodes = nodeArray.Where(n => !n.Moving).ToList(); if (newNodes.Any()) { _nodesSet.AddRange(newNodes); } var movingNodes = nodeArray.Where(n => n.Moving).ToList(); foreach (var node in movingNodes) { node.Moving = false; } _db.SaveChanges(); // Update the root ID if (isRoot) { nodeTreeRoot.RootId = ToNullableKey(nodeTreeRoot.Id); nodeTreeRoot.Root = nodeTreeRoot; _db.SaveChanges(); } else if (Equals(rootId, default(TNullableKey))) { var rootIds = newNodes.Select(n => n.RootId).Distinct().ToArray(); if (rootIds.Length > 1) { throw new ArgumentException("Unable to identify root node ID of node tree as multiple have been supplied."); } if (Equals(rootId, default(TNullableKey)) && rootIds.Length == 0 || (rootIds.Length == 1 && Equals(rootIds[0], default(TNullableKey)))) { rootId = rootIds[0]; //nodeTreeRoot.RootId = rootId;//ToNullableKey(GetNodes(rootId).Single(n => n.Left == 1).Id); } } if (!Equals(rootId, default(TNullableKey))) { foreach (var newNode in newNodes) { newNode.RootId = rootId; } _db.SaveChanges(); } else if (!isRoot) { throw new Exception("Unable to determine root ID of non-root node"); } // Update the parent IDs now we have them foreach (var newNode in newNodes) { if (newNode != nodeTreeRoot) { var path = GetPathToNode(newNode, newNodes).Reverse(); var current = newNode; foreach (var ancestor in path) { current.ParentId = (TNullableKey)(object)ancestor.Id; current = ancestor; } } } _db.SaveChanges(); return(newNodes); }
public T InsertNextTo(TNullableKey siblingId, List <T> nodeTree, NestedSetInsertMode insertMode) { return(Insert(default(TNullableKey), siblingId, nodeTree, insertMode).First()); }
public T InsertNextTo(TNullableKey siblingId, T node, NestedSetInsertMode insertMode) { return(Insert(default(TNullableKey), siblingId, new[] { node }, insertMode).First()); }
public List <T> InsertBelow(TNullableKey parentId, IEnumerable <T> nodeTree, NestedSetInsertMode insertMode) { return(Insert(parentId, default(TNullableKey), nodeTree, insertMode)); }
public T InsertBelow(TNullableKey parentId, T node, NestedSetInsertMode insertMode) { return(Insert(parentId, default(TNullableKey), new[] { node }, insertMode).First()); }
public List <T> InsertRoot(IEnumerable <T> nodeTree, NestedSetInsertMode insertMode) { return(Insert(default(TNullableKey), default(TNullableKey), nodeTree, insertMode)); }
public T InsertRoot(T node, NestedSetInsertMode insertMode) { return(Insert(default(TNullableKey), default(TNullableKey), new[] { node }, insertMode).First()); }
public void MoveToSibling(TKey nodeId, TNullableKey siblingId, NestedSetInsertMode insertMode) { Move(nodeId, default(TNullableKey), siblingId, insertMode); }
public void MoveToParent(TKey nodeId, TNullableKey parentId, NestedSetInsertMode insertMode) { Move(nodeId, parentId, default(TNullableKey), insertMode); }