Recursive hierarchical parent child

I have a set of items coming from a database that is parentid or null.

Here is my class:

 public class Item { public int id{get;set;} public string Name{get;set;} public int? ParentId{get;set;} public List<Item> SubItems{get;set;} } 

I want to build a hierarchical structure of elements from a collection. Suppose a collection contains 100 elements from which I need to build a structure based on a ParentId mapping.

I tried this post Recursive hierarchical joins in C # and LINQ but it gives me an error if ParentId is null.

Also tried Creating a list of tree types, recursively checking C # parent-child relationships , but this solution also does not work for me.

How do I achieve this?

+4
source share
3 answers

You can use this approach:

  • Get all items from the database (without filling in SubItems).
  • Create a Lookup<int?,Item> identifiers of the parent elements and elements with this parent identifier.
  • Scroll through the elements and associate each element with sub-elements using search.

the code:

 var items = // get from the database... (eg as a list) var lookup = items.ToLookup(x => x.ParentId); foreach (var item in items) item.SubItems = lookup[item.Id].ToList(); 

As @EamonNerbonne points out below, you can also get root elements if you need to:

 var roots = lookup[null].ToList(); 
+7
source

Do you really need a setter for sub items? Also, be aware of performance issues when running Select * queries on an SQL server.

  public List<Item> SubItems{ get { try{ var validParents = db.items.Where(x=>x.ParentId!=null && x.ParentId.Equals(Id)); //db is your dbcontext if(validParents !=null) { return validParents.ToList(); }else { return null; } catch(Exception) { return null; } } 

(Note: consider adding this to your incomplete entity class. Never name your entity โ€œItemโ€ :). An element is a reserved word. )

0
source

Using this Node class , you can simply do this:

 var flatListOfItems = GetItemsFromDatabase(); var rootNodes =Node<Item>.CreateTree(flatListOfItems, i => i.id, i => i.ParentId); 

Your elements no longer need subitems because the Node class has children and a descendant property. (Also ancestors, brothers and sisters, level, etc.).

The CreateTree method results in 1 or more rootnodes. If you are sure that there is always one rootnode, you can do rootNodes.Single () to get root.

0
source

Source: https://habr.com/ru/post/1495075/


All Articles