Attualmente sto cercando di capire un buon modo per ordinare i miei elementi con LINQ e C#, ma non riesco a farlo.LINQ ordina un elenco semplice in base all'infanzia
Per il problema cerchiamo suppone che si abbia la seguente tabella
---TempTable
ID (int)
ParentID (int)
Name (varchar)
SortOrder (int)
L'ID e ParentID sono legati gli uni agli altri e mi danno una struttura di dati gerarchica sé. Gli elementi radice hanno un valore null nel campo ID. Il SortOrder è solo una parte dell'intera tabella e basato sul ParentID, quindi gli elementi che condividono lo stesso ParentID hanno 1, 2, 3 in esso.
lascia supporre ulteriormente i seguenti dati:
ID = 1
ParentID = null
Name = Test 1
SortOrder = 1
ID = 2
ParentID = 1
Name = Test 2
SortOrder = 1
ID = 3
ParentID = 1
Name = Test 3
SortOrder = 2
ID = 4
ParentID = 2
Name = Test 4
SortOrder = 1
Mia lista piatto desiderato dovrebbe avere il seguente ordine:
Test 1 //root element with sort order 1 = very top
Test 2 //child element of root with sort order 1
Test 4 //child element of test 2 with sort order 1
Test 3 //child element of root with sort order 2
Inoltre mi piace per ottenere l'oggetto in sé, senza ottenere solo una parte delle informazioni ha gettato l'uso di selezionare nuovo ...
Questo è uno dei miei tentativi falliti:
from x in EntityModel.TempTables //DbSet<TempTable> by EntityFramework - which already holds all elements
orderby x.SortOrder
from y in x.TempTableChildren //Navigation Property by EntityFramework
orderby y.SortOrder
select y
Grazie in anticipo per il vostro aiuto.
Edit:
L'ordine con il ParentID forse disponibile, con il dato TestData, l'ID, ParentIDs sono in perfetto ordine, ma questo non è il caso in un'applicazione reale dal vivo in quanto i suoi dati driven, qualcuno potrebbe eliminare una voce di crearne uno nuovo e metterlo in un certo ordine sotto un genitore e si dovrebbe avere qualcosa di simile:
ID = 193475037
ParentID = 2
Name = Test 192375937
SortOrder = 25
Ora nell'applicazione sarebbe possibile spostare questa e la ParentID e SortOrder cambierebbe in modo casuale a qualcosa di simile:
ID = 193475037
ParentID = 456798424
Name = Test 192375937
SortOrder = 4
Per spiegare furhter il problema qui è un codice - come farei senza 1 bellissima Linq Query ma con 2 e alcuni dei rendimenti:
public class LinqTestDemo
{
Random rand = new Random();
List<TempTable> list = new List<TempTable>();
public List<TempTable> GetFlatData()
{
list = GetTestData();
var rootElement = (from x in list
where x.ParentID == null
orderby x.SortOrder
select x).ToList();
var flatList = OrderChilds(rootElement).ToList();
foreach (var tempTable in flatList)
{
Console.WriteLine(string.Format("ID = {0} - ParentID = {1} - Name = {2} - SortOrder = {3}", tempTable.ID, tempTable.ParentID, tempTable.Name, tempTable.SortOrder));
}
return flatList;
}
private IEnumerable<TempTable> OrderChilds(List<TempTable> enumerable)
{
foreach (var tempTable in enumerable)
{
yield return tempTable;
TempTable table = tempTable;
var childs = OrderChilds((from x in list
where x.ParentID == table.ID
orderby x.SortOrder
select x).ToList());
foreach (var child in childs)
{
yield return child;
}
}
}
public List<TempTable> GetTestData()
{
var returnValue = new List<TempTable>();
for (int i = 0; i < 50; i++)
{
var tempTable = new TempTable();
tempTable.ID = i;
if (i == 0)
tempTable.ParentID = null;
else
tempTable.ParentID = rand.Next(0, i);
var maxSortOrder = (from x in returnValue
where x.ParentID == tempTable.ParentID
select (int?)x.SortOrder).Max();
if (maxSortOrder.HasValue)
tempTable.SortOrder = maxSortOrder.Value + 1;
else
tempTable.SortOrder = 1;
tempTable.Name = string.Format("Test {0:00}", i);
returnValue.Add(tempTable);
}
return returnValue;
}
public class TempTable
{
public int ID { get; set; }
public int? ParentID { get; set; }
public string Name { get; set; }
public int SortOrder { get; set; }
}
}
@ breadth-first vs Depth-First Traversal: Dopo alcune letture direi che il mio risultato desiderato sarebbe Attraversamento di profondità, dove gli elementi alla stessa profondità di livello dovrebbero essere ordinati dalla proprietà SortOrder.
La tabella-struttura definisce una struttura ad albero - e, quindi, ci sono due modi per "attraversare" l'albero al fine di produrre una struttura piatta . Profondità primo: http://www.cs.bu.edu/teaching/c/tree/breadth-first/ Larghezza Primo: http://www.brpreiss.com/books/opus4/html/ page551.html Non è chiaro dal tuo esempio il tipo di attraversamento a cui ti stai riferendo. –
Dopo un po 'di lettura direi che il mio risultato desiderato sarebbe Attraversamento di profondità, dove gli elementi alla stessa profondità di livello dovrebbero essere ordinati dalla proprietà SortOrder. –
Quanti livelli di profondità ci sono? Se è possibile avere una profondità illimitata, non è possibile in una singola query. Anche il modo in cui funziona il framework di entità, fallisce su query di natura ricorsiva. L'unica soluzione è l'attraversamento di alberi. –