2013-10-02 25 views
5

Mi sono imbattuto in un problema di ordinamento molto difficile e mi chiedo se qualcuno là fuori possa aiutarmi a capirlo. Fondamentalmente ho una tabella SQL completa delle seguenti informazioni:Ordinamento gerarchico difficile

ID (The comment's Unique Identifier) 

Previous ID (The ID of the comment that is being replied to with this comment) 

Position (The position of how "deep" the comment is, a post directly on a 
page would be "1" a reply to that "2", etc. 

E 'possibile con queste informazioni per ordinare utilizzando C#/LINQ in modo tale che possa essere restituito nell'ordine corretto quando viene chiamato?

Un esempio potrebbe essere il seguente:

ID | Position | PreviousID | Message| 

1 | 1  | 0   | Hello 
2 | 1  | 0   | How 
3 | 2  | 1   | There! 
4 | 2  | 2   | Are 
5 | 3  | 4   | You? 

sarebbe risolto nel seguente ordine:

1. Hello 
2. There! 
3. How 
4. Are 
5. You? 

Sto avendo dei problemi confezionamento mia testa intorno a come questo possa essere fatto o se si tratta di anche possibile, quindi apprezzerei molto anche solo una piccola spinta nella giusta direzione, grazie!

E solo per qualche informazione in più, questo è un tavolo esistente con un sacco di contenuti che non possono essere cancellati, ho solo bisogno di trovare un modo per ordinarlo in questo modo.

+0

sono abbastanza sicuro http://stackoverflow.com/questions/17968069/linq-sort-a-flat-list-based-on-childorder dovrebbe lavoro per te, se sto leggendo questo correttamente. –

risposta

2

LINQ può modellare questo con Hierarchical entra a far parte

ecco un esempio di Recursive Hierarchical Joins in C# and LINQ e dà una semplice passeggiata che fa ciò che si vuole.

Le chiavi sono leggermente diverse ma dovresti essere in grado di mappare sull'esempio.

1

Questo è più un problema di attraversamento dell'albero che un problema di ordinamento.

Ecco quello che è raccomando:

static IEnumerable<T> PreOrderTraverse<T>(IEnumerable<T> nodes, Func<T, IEnumerable<T>> childrenSelector) 
{ 
    foreach (var node in nodes) 
    { 
     yield return node; 

     foreach (var descendant in PreOrderTraverse(childrenSelector(node), childrenSelector)) 
     { 
      yield return descendant; 
     } 
    } 
} 

static void Main(string[] args) 
{ 
    /* Some code to load comments*/ 

    var children = comments.ToLookup(c => c.PreviousID); 

    var result = PreOrderTraverse(children[0], c => children[c.ID]); 

    foreach (var comment in result) 
    { 
     Console.WriteLine(comment.Message); 
    } 
}