Ich versuche derzeit, eine gute Möglichkeit zu finden, meine Elemente mit LINQ und C# zu sortieren, aber ich versäume es irgendwie.LINQ sortiere eine flache Liste basierend auf Kinder
Für das Problem lassen annimmt, dass Sie die folgende Tabelle
---TempTable
ID (int)
ParentID (int)
Name (varchar)
SortOrder (int)
Die ID und ParentID ist miteinander verwandt und geben Sie mir eine Selbst hierarchische Datenstruktur haben. Die Wurzelelemente haben eine Null im ID-Feld. Der SortOrder ist nur ein Teil der gesamten Tabelle und basiert auf der ParentID, so dass die Elemente, die dieselbe ParentID teilen, 1, 2, 3 enthalten.
Nehmen wir an, weiter die folgenden Daten:
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
flache Liste Mein Wunsch sollte folgende Reihenfolge haben:
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
Auch ich mag selbst das Objekt erhalten, ohne nur einen Teil der Informationen zu erhalten warf die Verwendung von ausgewählten neuen ...
Dies ist einer meiner gescheiterten Versuche:
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
Vielen Dank im Voraus für Ihre Hilfe.
Edit:
Der Auftrag mit dem ParentID vielleicht hilfreich, mit dem angegebenen Testdata, da die ID, sind ParentIDs in perfekter Ordnung, aber dies ist nicht der Fall in einem echten Live-Anwendung seit seiner Daten getrieben, jemand könnte löschen eines Eintrags eine neue erstellen und sie in einer bestimmten Reihenfolge unter einem Elternteil platzieren und Sie müssten so etwas wie:
ID = 193475037
ParentID = 2
Name = Test 192375937
SortOrder = 25
nun in der Anwendung wäre es möglich, diese zu bewegen und die ParentID und SortOrder würde sich ändern zufällig zu etwas wie:
ID = 193475037
ParentID = 456798424
Name = Test 192375937
SortOrder = 4
furhter Um das Problem hier zu erklären, ist ein Code - wie ich es ohne 1 beautifull Linq Abfrage tun würde, aber mit 2 und einige yield return:
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; }
}
}
@ Breiten Erste vs Depth-First Traversal: Nach einigem Lesen würde ich sagen, dass mein gewünschtes Ergebnis Tiefentiefe Traversal wäre, wo die Elemente in der gleichen Tiefentiefe von der Eigenschaft SortOrder geordnet werden sollen.
Ihre Tisch-Struktur definiert eine Baumstruktur - und damit gibt es zwei Möglichkeiten, um „durchqueren“, um den Baum, um eine flache Struktur zu erzeugen, . erste Tiefe: http://www.cs.bu.edu/teaching/c/tree/breadth-first/ Breite Erstens: http://www.brpreiss.com/books/opus4/html/ page551.html Aus Ihrem Beispiel ist nicht klar, auf welchen Traversal-Typ Sie sich beziehen. –
Nach einigem Lesen würde ich sagen, dass mein gewünschtes Ergebnis Tiefentiefe Traversal wäre, wo die Elemente in der gleichen Tiefentiefe von der Eigenschaft SortOrder geordnet werden sollen. –
Wie viele Ebenen der Tiefe gibt es? Wenn Sie unbegrenzte Tiefe haben können, ist dies nicht in einer einzigen Abfrage möglich. Auch die Funktionsweise des Entity-Frameworks schlägt bei rekursiven Abfragen fehl. Die einzige Lösung ist das Traversieren von Bäumen. –