使用LINQ递归添加Parent

时间:2013-08-02 16:13:54

标签: c# .net linq extension-methods

我为MenuItem定义了以下类

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

以下是所有菜单项的集合

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}};

现在我只有一个从数据库中检索过的菜单项,即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

//但我还需要包含所有父ID菜单项。

在这种情况下Level2-ALevel1-A

如何在C#中包含它?欢迎使用LINQ或任何扩展方法

2 个答案:

答案 0 :(得分:2)

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;
}

这将导致对数据库的多次查询。如果您不希望发生这种情况,则需要使用recursive CTE.

等数据库功能编写自己的SQL查询

答案 1 :(得分:0)

更改MenuItem,使其具有可为空的parentId:

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

使用此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);

现在你需要做的就是:

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