I have a collection of items coming from a database which has a parentid
value or null.
Here is my class design:
public class Item
{
public
You could use this approach:
Lookup<int?,Item>
of parent ids and items with that parent id.Code:
var items = // get from the database... (e.g. as a list)
var lookup = items.ToLookup(x => x.ParentId);
foreach (var item in items)
item.SubItems = lookup[item.Id].ToList();
As @EamonNerbonne commented below, you can get the root elements as well, if you need to:
var roots = lookup[null].ToList();
Do you really need a setter for sub items? Also be mindful of the performance issues when you run Select* queries on 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: Think of adding this to your partial entity class. Never name your entity as "Item" :).Item is a reserved word. )
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 items doesn't need the subitems anymore because the Node class has a children and a descendants property. (Also ancestors, siblings, level etc.).
The CreateTree method results in 1 or more rootnodes. If you are sure that there is always 1 rootnode, you can do rootNodes.Single() to get the root.