我有一个来自数据库的项目集合,其值为parentid
或为空。
这是我的班级设计:
public class Item
{
public int id{get;set;}
public string Name{get;set;}
public int? ParentId{get;set;}
public List<Item> SubItems{get;set;}
}
我想从集合中构建Items的层次结构。假设一个集合是100个项目,我需要根据ParentId映射构建结构。
我试过这篇文章Recursive Hierarchical Joins in C# and LINQ 但如果ParentId为null,它会给我一个错误。
还尝试了Build tree type list by recursively checking parent-child relationship C#,但此解决方案对我来说也不起作用。
我如何实现这一目标?
答案 0 :(得分:7)
你可以使用这种方法:
Lookup<int?,Item>
个父ID和项目。代码:
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();
如下所示 @EamonNerbonne ,如果您需要,还可以获取根元素:
var roots = lookup[null].ToList();
答案 1 :(得分:0)
你真的需要一个子项目的setter吗?在SQL服务器上运行选择* 查询时,请注意性能问题。
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;
}
}
(注意:考虑将此添加到您的部分实体类。永远不要将您的实体命名为“Item”:)。Item是保留字。 )
答案 2 :(得分:0)
使用此Node class,您只需执行此操作:
var flatListOfItems = GetItemsFromDatabase();
var rootNodes =Node<Item>.CreateTree(flatListOfItems, i => i.id, i => i.ParentId);
您的项目不再需要子项,因为Node类具有子项和后代属性。 (还有祖先,兄弟姐妹,等级等)。
CreateTree方法会生成一个或多个根节点。如果你确定总有1个rootnode,你可以使用rootNodes.Single()来获取root。