简体   繁体   English

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

[英]Performing a Parent then Child sort in Linq

The intention is to sort the list by the parent, and then the child (there will only be one child). 目的是按照父级,然后是子级(只有一个子级)对列表进行排序。

Example Set:
ID  ParentId Type   Unit
1   NULL    Energy  kJ
2   1       Cal
3   NULL    Protein g
4   NULL    Fat, total  g
5   4       Saturated   g
6   NULL    Carbohydrate    g
7   6       Sugars  g
8   NULL    Dietary fibre   g
10  NULL    Sodium  mg
11  NULL    Potassium   mg

So for example, if I sort by Type (alphabetical order) it would come up 例如,如果我按类型(字母顺序)排序

  1. Carbohydrate 糖类
  2. Sugars (parent = 1.) 糖(父母= 1.)
  3. Dietary fibre 膳食纤维
  4. Energy 能源
  5. Cal (parent = 4.) 校准(父母= 4)
  6. Fat, total 脂肪总计
  7. Saturated (parent = 6.) 饱和(父代= 6)。

Try this: 尝试这个:

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

This could be done in two steps. 这可以分两步完成。 First - building parent-child hierarchy (and sorting it): 首先-建立父子层次结构(并对其进行排序):

var query = from parent in data
            where parent.ParentId == null
            orderby parent.Type
            join child in data on parent.ID equals child.ParentId into g
            select new { Parent = parent, Children = g };

Second - flattering hierarchy 第二-讨人喜欢的等级

var result = query.Flatten(x => x.Parent, x => x.Children);

For flattering I used extension method: 为了讨人喜欢,我使用了扩展方法:

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

This should work 这应该工作

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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM