我正在使用C#
,并且我有一个具有可空父ID属性的项目列表。
我需要将此项转换为包含其子项列表的项目列表,并继续向下生成,直到没有项目为止。
我现有的课程
public class Item
{
public int Id { get; set; }
public int? ParentId { get; set; }
}
我的第一个想法......
创建一个类
public class ItemWithChildren
{
public Item Item { get; set; }
public List<ItemWithChildren> Children { get; set; }
}
现在我需要一些方法来获得一个List<ItemWithChildren>
,它将所有顶级Item对象及其子项放入Children
属性。
请注意,嵌套不是设定的级别数。
我希望有一个优雅的LINQ查询可以工作。到目前为止我只有这个......
var itemsWithChildren = items.Select(a => new ItemWithChildren{ Item = a });
答案 0 :(得分:4)
不使用纯Linq执行此任务更具可读性,而是Linq和循环的混合。
给出以下容器:
class Node
{
public int Id { get; set; }
public int? ParentId { get; set; }
public List<Node> Children { get; set; }
}
然后您可以使用以下代码创建树。
var nodes = new List<Node>
{
new Node{ Id = 1 },
new Node{ Id = 2 },
new Node{ Id = 3, ParentId = 1 },
new Node{ Id = 4, ParentId = 1 },
new Node{ Id = 5, ParentId = 3 }
};
foreach (var item in nodes)
{
item.Children = nodes.Where(x => x.ParentId.HasValue && x.ParentId == item.Id).ToList();
}
var tree = nodes.Where(x => !x.ParentId.HasValue).ToList();
这将处理任何级别的深度并返回正确的树。
给出以下打印树的方法:
private void PrintTree(IEnumerable<Node> nodes, int indent = 0)
{
foreach(var root in nodes)
{
Console.WriteLine(string.Format("{0}{1}", new String('-', indent), root.Id));
PrintTree(root.Children, indent + 1);
}
}
此调用的输出为:
1
-3
--5
-4
2
如果您想使用纯Linq,可以执行以下操作,但对我来说更难阅读:
var tree = nodes.Select(item =>
{
item.Children = nodes.Where(child => child.ParentId.HasValue && child.ParentId == item.Id).ToList();
return item;
})
.Where(item => !item.ParentId.HasValue)
.ToList();
答案 1 :(得分:2)
这可能有帮助吗?
var itemsWithChildren = items.Select(a => new ItemWithChildren{
Item = a,
Children = items.Where(b => b.ParentId==a.Id)
.ToList()
});
答案 2 :(得分:0)
然后更新模型以实现它
public string Name { get; set; }
[DisplayName("Parent Category")]
public virtual Guid? CategoryUID { get; set; }
public virtual ICollection<Category> Categories { get; set; }
答案 3 :(得分:0)
我认为你需要分两步完成...... 我已经测试过,它肯定有用......
var items = new List<Item>();
items.Add(new Item { Id = 1, ParentId = null });
items.Add(new Item { Id = 2, ParentId = 1 });
items.Add(new Item { Id = 3, ParentId = 1 });
items.Add(new Item { Id = 4, ParentId = 3 });
items.Add(new Item { Id = 5, ParentId = 3 });
var itemsWithChildren = items.Select(a =>
new ItemWithChildren { Item = a }).ToList();
itemsWithChildren.ForEach(a =>
a.Children = itemsWithChildren.Where(b =>
b.Item.ParentId == a.Item.Id).ToList());
var root = itemsWithChildren.Single(a => !a.Item.ParentId.HasValue);
Console.WriteLine(root.Item.Id);
Console.WriteLine(root.Children.Count);
Console.WriteLine(root.Children[0].Children.Count);
Console.WriteLine(root.Children[1].Children.Count);
...输出
1 2 0 2