Recursive Hierarchical Joins with Depth

2019-07-18 01:49发布

I followed this Recursive Hierarchical Joins in C# and LINQ post to implement recursive join extension to show a tree view data in my application. As i have 15000 tree nodes, the jQuery DynaTree at client side preparation takes lot of time (50 Secs) in buggy browser I.E 7&8

To avoid this i decided to load only one level initially, then load other children on demand (Lazy Loading).

But i could not see the effect in setting depth in recursive join. Even i specify, it prepare all nodes.

public static List<DynaTreeNode> GenerateTreeByDepth(List<NodeDTO> nodeList, 
   int deepLevel)
  {

  StringBuilder hirTree = new StringBuilder();
  List<DynaTreeNode> tree = new List<DynaTreeNode>();

  IEnumerable<DynaTreeNode> nodes = nodeList.RecursiveJoin
  (element => element.DataPointSK,element => element.DataPointSKParent,
  (NodeDTO element, int index, int depth,IEnumerable<DynaTreeNode> childNodes) => 
                new DynaTreeNode()
               {
                   title = element.DataPoint,
                   key = element.DataPointSK.ToString(),
                   children = childNodes.ToList(),
                   select = element.selected,
                   expand = element.selected,                      
                   Depth = deepLevel
               });
        tree = nodes.ToList();          
        return tree;

    }

I tried setting depth

Depth = deepLevel

But no use. What could be the issue? How can i do this?

1条回答
爱情/是我丢掉的垃圾
2楼-- · 2019-07-18 02:20

RecursiveJoin extension method is used to build a tree out of raw nodes. The overload you are using has int depth parameter passed, to initialize new created node with level at which it will reside, and has nothing to do with depth of the tree which is built.

Extension by itself is lazy. When you first invoke RecursiveJoin, it will return IEnumerable<> of roots, which is not materialized until you start enumerating.

Problem with your code is that you eagerly convert IEnumerable<> of children into list:

children = childNodes.ToList()

This forces materialization of children collection, recursively calls same method again to construct DynaTreeNode, and repeats for all levels. Try to replace children list in DynaTreeNode with IEnumerable - this will produce DynaTreeNodes on demand.

Or you can keep list, and replace line above with following code:

chidren = depth >= deepLevel ? null : childNodes.ToList()

This will cut off tree at the passed level, as expected.

查看更多
登录 后发表回答