C# 基于Linq c的多级父子关系排序#
我有一个列表,我需要将它排序到这个层次结构C# 基于Linq c的多级父子关系排序#,c#,asp.net,linq,list,guid,C#,Asp.net,Linq,List,Guid,我有一个列表,我需要将它排序到这个层次结构 { Id=1, ParentId = null, Name = "Item1", Type="0"} { Id=2, ParentId = 1, Name = "ItemChild1", Type="1"} { Id=3, ParentId = 1, Name = "ItemChild2", Type="1"} { Id=4, ParentId = 3, Name = "ItemGrandChild1", Type="2"}
{ Id=1, ParentId = null, Name = "Item1", Type="0"}
{ Id=2, ParentId = 1, Name = "ItemChild1", Type="1"}
{ Id=3, ParentId = 1, Name = "ItemChild2", Type="1"}
{ Id=4, ParentId = 3, Name = "ItemGrandChild1", Type="2"}
{ Id=5, **ParentId = 1**, Name = "ItemGrandChild2", Type="2"}
{ Id=6, ParentId = null, Name = "Item7", Type="0"}
...
与正常的父子关系不同,这里
类型2的项可以是类型1或类型0的子项
所有Id都是GUID
我见过may使用Linq在子-父排序上堆叠答案。但我的情况不同。
使用Linq的任何优雅方法?创建查找以快速查找子项并将其投影到父集合。在我看来,这根本不取决于您的孩子是否有不同的类型,只要他们知道哪个元素是他们的父元素
public class TreeItem
{
public int Id { get; set; }
public int? ParentId { get; set; }
public IEnumerable<TreeItem> Children { get; set; }
public void PrintAllChildren()
{
this.PrintAllChildren(0);
}
private void PrintAllChildren(int indent)
{
Debug.WriteLine("{1}Item id: {0}", this.Id, string.Concat(Enumerable.Repeat<int>(0, indent).Select(i => " ")));
if (this.Children != null)
foreach (var item in this.Children)
item.PrintAllChildren(indent + 1);
}
}
public static class TreeItemExtension
{
public static IEnumerable<TreeItem> GetAsTree(this IEnumerable<TreeItem> data)
{
var lookup = data.ToLookup(i => i.ParentId);
return lookup[null].Select(i => {
i.FillChildren(lookup);
return i;
});
}
private static TreeItem FillChildren(this TreeItem item, ILookup<int?, TreeItem> lookup)
{
item.Children = lookup[item.Id].Select(i => i.FillChildren(lookup));
return item;
}
}
公共类树项
{
公共int Id{get;set;}
public int?ParentId{get;set;}
公共IEnumerable子项{get;set;}
public void printalchildren()
{
这是printalchildren(0);
}
私有void printalchildren(int缩进)
{
Debug.WriteLine(“{1}项id:{0}”,this.id,string.Concat(Enumerable.Repeat(0,缩进)。Select(i=>”);
if(this.Children!=null)
foreach(此.Children中的变量项)
项目.打印所有子项(缩进+1);
}
}
公共静态类树扩展
{
公共静态IEnumerable GetAsTree(此IEnumerable数据)
{
var lookup=data.ToLookup(i=>i.ParentId);
返回查找[null]。选择(i=>{
i、 填充子项(查找);
返回i;
});
}
私有静态TreeItem FillChildren(此TreeItem项,ILookup查找)
{
item.Children=lookup[item.Id]。选择(i=>i.FillChildren(lookup));
退货项目;
}
}
如果我是你,我会放弃尝试使用linq或sql对其进行排序。抽象可能会有帮助,但在这样复杂的情况下,它们只会妨碍您
如果您只编写自己的分类器,将节省大量时间
class MyCompare : IComparer<MyObject>
{
public int Compare(x1, x2)
{
if (x1.parent == parent1 && x2.parent == parent2)
return 1;
if (x1.parent == x2.parent)
return 0;
//ect
}
}
List<MyObject> list = GetWeirdObjects();
list.Sort(new MyCompare());
class MyCompare:IComparer
{
公共整数比较(x1,x2)
{
如果(x1.parent==parent1&&x2.parent==parent2)
返回1;
如果(x1.parent==x2.parent)
返回0;
//ect
}
}
List List=GetWeirdObjects();
list.Sort(新的MyCompare());