2012-10-19 11 views
8

L'intenzione è di ordinare l'elenco in base al genitore, quindi al figlio (ci sarà un solo figlio).Esecuzione di una parent e poi ordinamento figlio in 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 

Così, per esempio, se io Classificare per Tipo (ordine alfabetico) che sarebbe venuto

  1. Carboidrati
  2. Zuccheri (genitore = 1.)
  3. La fibra alimentare
  4. Energia
  5. Cal (genitore = 4)
  6. Grasso, totale
  7. saturi (genitore = 6.)
+1

quando si dice dal genitore e il n da bambino, intendi gli ID? O vuoi dire che vuoi vedere P1, C1, P2, C2, P3, C3, ecc ...? È una buona domanda, non è chiaro esattamente quali risultati vorresti vedere. Forse un campione che mostra i risultati che ti aspetteresti? –

+0

@JamesMichaelHare Aggiunto set previsto in – ediblecode

+0

Suppongo che dai tuoi dati sia garantito che un id figlio non sia mai maggiore del suo id genitore? –

risposta

4

Prova questa:

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

Questo funziona. Solo per gli utenti futuri: dovrebbe essere '.ThenBy (x => x.item.Parent == null)' – ediblecode

+0

Oops. Modificato. Grazie per averlo capito. – Bobson

+1

Ah sì, questo in realtà non funziona, sembrava solo perché i miei dati erano già nel giusto ordine. – ediblecode

1

Ciò potrebbe essere fatto in due fasi. In primo luogo - la costruzione di gerarchia padre-figlio (e smistamento):

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

In secondo luogo - lusinghiero gerarchia

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

seducenti ho usato metodo di estensione:

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

Questo dovrebbe funzionare

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

Apparentemente 'c' non esiste nel contesto attuale – ediblecode

+0

@danrhul - Spiacente, dovrebbe essere stato x.ParentId – Aducci

+0

Non funziona Ho paura, 6 null, seguito da dati ripetuti casuali – ediblecode

Problemi correlati