C# 在Linq中执行父级然后子级排序

C# 在Linq中执行父级然后子级排序,c#,.net,linq,linq-to-sql,C#,.net,Linq,Linq To Sql,这样做的目的是按父级排序,然后按子级排序(只有一个子级) 例如,如果我按类型(字母顺序)排序,它会出现 碳水化合物 糖(母体=1。) 膳食纤维 精力 校准(父项=4。) 总脂肪 饱和(母体=6。) 试试这个: return myData.Select(x => new { key = (x.Parent ?? x).Type, item = x}) .OrderBy(x => x.key) .ThenBy(x => x.ite

这样做的目的是按父级排序,然后按子级排序(只有一个子级)

例如,如果我按类型(字母顺序)排序,它会出现

  • 碳水化合物
  • 糖(母体=1。)
  • 膳食纤维
  • 精力
  • 校准(父项=4。)
  • 总脂肪
  • 饱和(母体=6。)
  • 试试这个:

    return myData.Select(x => new { key = (x.Parent ?? x).Type, item = x})
                 .OrderBy(x => x.key)
                 .ThenBy(x => x.item.Parent != null)
                 .Select(x => x.item);
    

    这可以分两步完成。首先-构建父子层次结构(并对其排序):

    第二层次

    var result = query.Flatten(x => x.Parent, x => x.Children);
    
    为了奉承,我使用了扩展方法:

    public static IEnumerable<TResult> Flatten<T, TResult>(
        this IEnumerable<T> sequence, 
        Func<T, TResult> parentSelector,
        Func<T, IEnumerable<TResult>> childrenSelector)
    {
        foreach (var element in sequence)
        {
            yield return parentSelector(element);
    
            foreach (var child in childrenSelector(element))
                yield return child;
        }
    }    
    
    公共静态IEnumerable展平(
    这个可数序列,
    Func parentSelector,
    Func儿童选择器)
    {
    foreach(序列中的var元素)
    {
    收益率选择器(元素);
    foreach(childrenSelector(元素)中的var child)
    退换子女;
    }
    }    
    
    这应该行得通

    var query = from p in context.Table
                from c in context.Table.Where(x => p.ID == x.ParentId)
                                       .DefaultIfEmpty()
                let hasNoParent = c == null
                orderby hasNoParent ? p.Type : c.Type, hasNoParent ? 0 : 1
                select hasNoParent ? p.Type : c.Type;
    

    你说的是父母,然后是孩子,你是指身份证吗?或者你的意思是你想看P1、C1、P2、C2、P3、C3等等。。。?这是一个好问题,只是不清楚你希望看到什么样的结果。也许一个示例显示了您期望的结果?@JamesMichaelHare添加了期望集inI,该示例会假设从您的数据中可以保证您的子id永远不会大于其父id?@JamesMichaelHare是的,当前是,但可能并不总是这样。这是有效的。仅针对未来用户:它应该是
    。然后是(x=>x.item.Parent==null)
    Oops。编辑。谢谢你抓到了。啊,是的,这实际上不起作用,只是因为我的数据已经按正确的顺序排列了。看起来是按Id列排序的。我在上面的表中添加了另一个元素,其parentId为1。但它是最后一个出现的。尝试将.ToList()放在.ThenBy()后面吗?在更改我们选择的内容之前,强制它评估排序。显然,
    c
    在当前数据库中不存在context@danrhul-对不起,应该是x.parentId不起作用,恐怕是6个空值,后面是随机重复的数据,我有,但仍然没有注意到
    p:c
    的变化,它只是复制了几条记录,然后按字母顺序显示它们。
    public static IEnumerable<TResult> Flatten<T, TResult>(
        this IEnumerable<T> sequence, 
        Func<T, TResult> parentSelector,
        Func<T, IEnumerable<TResult>> childrenSelector)
    {
        foreach (var element in sequence)
        {
            yield return parentSelector(element);
    
            foreach (var child in childrenSelector(element))
                yield return child;
        }
    }    
    
    var query = from p in context.Table
                from c in context.Table.Where(x => p.ID == x.ParentId)
                                       .DefaultIfEmpty()
                let hasNoParent = c == null
                orderby hasNoParent ? p.Type : c.Type, hasNoParent ? 0 : 1
                select hasNoParent ? p.Type : c.Type;