2012-10-19 14 views
8

Celem jest posortowanie listy według rodzica, a następnie dziecka (będzie tylko jedno dziecko).Wykonywanie zadania nadrzędnego, a następnie sortowanie podrzędnego w 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 

Tak na przykład, jeśli Sortuj wg kolejności alfabetycznej) (byłoby wymyślić

  1. węglowodan
  2. Cukry (rodzic = 1)
  3. Błonnik
  4. Energy
  5. Cal (rodzic = 4.)
  6. Tłuszcz, ogółem
  7. Nasycone (rodzic = 6.)
+1

kiedy mówisz przez rodziców i n przez dziecko, masz na myśli identyfikatory? Czy masz na myśli, że chcesz zobaczyć P1, C1, P2, C2, P3, C3 itd ...? To dobre pytanie, nie wiadomo dokładnie, jakie wyniki chciałbyś zobaczyć. Być może próbka pokazująca wyniki, których można się spodziewać? –

+0

@JamesMichaelHare Dodano oczekiwany zestaw w – ediblecode

+0

Założę się, że z twoich danych masz gwarancję, że identyfikator podrzędny nigdy nie jest większy od jego identyfikatora nadrzędnego? –

Odpowiedz

4

Spróbuj tego:

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

To działa. Tylko dla przyszłych użytkowników: powinno to być '.ThenBy (x => x.item.Parent == null)' – ediblecode

+0

Ups. Edytowane. Dzięki za złapanie tego. – Bobson

+1

Ah tak, to właściwie nie działa, po prostu wydawało się, ponieważ moje dane były już we właściwej kolejności. – ediblecode

1

Można to zrobić w dwóch etapach. Po pierwsze - budowanie hierarchii rodzic-dziecko (i sortowania go):

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

drugie - pochlebne hierarchia

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

Dla pochlebne użyłem metodę rozszerzenia:

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

To powinno działać

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

Podobno 'c' nie istnieje w bieżącym kontekście – ediblecode

+0

@danrhul - Przepraszam, powinno być x.ParentId – Aducci

+0

Nie działa Obawiam się, 6 wartości null, a następnie losowe powtarzanie danych – ediblecode

Powiązane problemy