Billa
Billa

Reputation: 5266

Add Parent recursively using LINQ

I have the following class defined for MenuItem

public class MenuItem
{
    public int Id { get; set; }
    public string Key { get; set; }     
    public int ParentId { get; set; }
    public string Url { get; set; }        
}

Also below is the collection of all menu items

List<MenuItem> allMenu=new List<MenuItem>
  {new MenuItem{Id=1,Key="Level1-A",Url="url1"},
  {new MenuItem{Id=2,Key="Level1-B",Url="url2"},
  {new MenuItem{Id=3,Key="Level2-A",Url="url3", ParentId=1},
  {new MenuItem{Id=4,Key="Level3-AA",Url="url1", ParentId=3}};

Now I have only one menu item retreived from DB, that is Level3-AA

MenuItem item=new MenuItem{Id=4,Key="Level3-AA",Url="url1", ParentId=3};

 allMenu.FindAll(m=>m.Id==item.Id) //gives only one element Level3-AA

//But i need to include all parent id menuitem also.

In this case Level2-A and Level1-A

How can I include this in C#? using LINQ or any extension method are welcome

Upvotes: 1

Views: 434

Answers (2)

Alex Siepman
Alex Siepman

Reputation: 2608

Change the MenuItem so it has a nullable parentId:

public class MenuItem
{
    public int Id { get; set; }
    public string Key { get; set; }
    public int? ParentId { get; set; }
    public string Url { get; set; }
}

Get the nodes, using this Node class:

var allMenus=new List<MenuItem>
    {new MenuItem{Id=1,Key="Level1-A",Url="url1"},
    new MenuItem{Id=2,Key="Level1-B",Url="url2"},
    new MenuItem{Id=3,Key="Level2-A",Url="url3", ParentId=1},
    new MenuItem{Id=4,Key="Level3-AA",Url="url1", ParentId=3}};

// Creates trees based on Id and ParentId, 
// in this case there are 2 trees, the second with only item with Id 2
var rootNode = Node<MenuItem>.CreateTree(allMenus, m => m.Id, m => m.ParentId).First();

var targetNode = rootNode.Descendants.Single(n => n.Value.Id == 4);

Now all you have to do is this:

// Get the values of the ancestors (all the parents and their parents)
var ancestorValues = targetNode.Ancestors.Values();

Upvotes: 0

Todd Li
Todd Li

Reputation: 3269

List<MenuItem> all = new List<MenuItem>();
all.Add(item);

while (item.ParentId != 0) // Ideally you should use Nullable<int>
{
    var parent = allMenu.Single(m => m.Id = item.ParentId);
    all.Add(parent);
    item = parent;
}

This will result in multiple queries to the database though. If you don't want this to happen you'll need to write your own SQL query with database features like recursive CTE.

Upvotes: 2

Related Questions