2012-10-19 3 views
8

부모를 기준으로 목록을 정렬 한 다음 하위를 하나씩 선택합니다.Linq에서 부모를 수행 한 다음 하위 정렬

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 

그래서 예를 들어, 나는 종류의 유형 (알파벳 순서)으로는

  • 설탕 (부모 = 1)
  • 식이 섬유
  • 에너지

    1. 탄수화물을 마련한다면
    2. Cal (부모 = 4)
    3. 지방, 합계
    4. 포화 (부모 = 6)
  • +1

    부모님과 아이에 의해, ID를 의미합니까? 아니면 P1, C1, P2, C2, P3, C3 등을보고 싶습니까? 좋은 질문입니다. 어떤 결과를보고 싶은지 정확히 알 수 없습니다. 아마도 예상했던 결과를 보여주는 샘플일까요? –

    +0

    @JamesMichaelHare 추가 예상 집합이 – ediblecode

    +0

    에 추가되었습니다. 귀하의 데이터에서 자녀 아이디가 상위 아이디보다 클 수 없다는 보장이 있습니까? –

    답변

    4

    이 시도 :

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

    이것은 작동합니다. 미래 사용자를 위해서 : 그것은'.ThenBy (x => x.item.Parent == null)' – ediblecode

    +0

    이어야합니다. 편집 됨. 그것을 잡아 주셔서 감사합니다. – Bobson

    +1

    아, 그래, 이건 실제로 작동하지 않습니다, 내 데이터가 이미 올바른 순서로 있기 때문에 그냥 보였다. – ediblecode

    1

    이 두 단계로 수행 할 수있다. 첫째 - 상위 - 하위 계층 구조를 구축 (및 분류) : - :

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

    작동합니다

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

    둘째 아첨 계층

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

    I 아첨의 경우는 확장 방법을 사용

    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; 
    
    +0

    현재 'c'가 현재 컨텍스트에 존재하지 않습니다. – ediblecode

    +0

    @danrhul - 죄송합니다. x 여야합니다.상위 항목 – Aducci

    +0

    작동하지 않았습니다. 무효화되고 무작위로 반복되는 데이터가 뒤 따릅니다. – ediblecode

    관련 문제