Tôi hiện đang cố gắng tìm ra cách tốt để sắp xếp các phần tử của mình với LINQ và C#, nhưng tôi không thể làm như vậy.LINQ sắp xếp một danh sách phẳng dựa trên childorder
Đối với vấn đề chúng ta hãy giả sử bạn có bảng sau
---TempTable
ID (int)
ParentID (int)
Name (varchar)
SortOrder (int)
ID và ParentID có liên quan đến nhau và đưa cho tôi một cấu trúc dữ liệu tự hierachical. Các phần tử gốc có một giá trị rỗng trong trường ID. SortOrder chỉ là một phần của toàn bộ bảng và dựa trên ParentID, vì vậy các phần tử chia sẻ cùng một ParentID có 1, 2, 3 trong đó.
Cho phép tiếp tục đảm nhận các dữ liệu sau:
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
danh sách phẳng mong muốn của tôi nên có trình tự sau:
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
Ngoài ra tôi muốn để có được những đối tượng riêng của mình mà không chỉ nhận được một phần của thông tin đã sử dụng lựa chọn mới ...
Đây là một trong những lần thử không thành công của tôi:
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
Cảm ơn trước sự giúp đỡ của bạn.
Edit:
Trình tự với ParentID có thể hữu ích, với TestData trao kể từ ID, ParentIDs nằm trong trật tự hoàn hảo nhưng điều này isnt trường hợp trong một ứng dụng thực sự sống kể từ khi dữ liệu của nó điều khiển, ai đó có thể xóa một mục tạo một hình mới và đặt nó theo một thứ tự nhất định theo cha mẹ và bạn sẽ có một cái gì đó như:
ID = 193475037
ParentID = 2
Name = Test 192375937
SortOrder = 25
Bây giờ trong việc áp dụng nó sẽ có thể di chuyển một này và ParentID và SortOrder sẽ thay đổi ngẫu nhiên cho một cái gì đó như:
ID = 193475037
ParentID = 456798424
Name = Test 192375937
SortOrder = 4
Để furhter giải thích các vấn đề ở đây là một số mã - làm thế nào tôi sẽ làm điều đó mà không cần 1 beautifull LINQ Query nhưng với 2 và một số 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; }
}
}
@ Breadth-First vs Depth-First Traversal: Sau khi đọc một số tôi sẽ nói kết quả mong muốn của tôi sẽ là Depth-First Traversal, trong đó các phần tử ở cùng độ sâu nên được sắp xếp theo thuộc tính SortOrder.
bảng cấu trúc của bạn định nghĩa một cấu trúc cây - và do đó, có hai cách để "đi qua" cây để tạo ra một cấu trúc phẳng . Độ sâu đầu tiên: http://www.cs.bu.edu/teaching/c/tree/breadth-first/ Chiều rộng đầu tiên: http://www.brpreiss.com/books/opus4/html/ page551.html Không rõ ràng trong ví dụ của bạn về loại truyền tải mà bạn đang đề cập đến. –
Sau khi đọc một số tôi sẽ nói kết quả mong muốn của tôi sẽ là Depth-First Traversal, trong đó các phần tử ở độ sâu cùng cấp phải được sắp xếp theo thuộc tính SortOrder. –
Có bao nhiêu cấp độ sâu? Nếu bạn có thể có chiều sâu không giới hạn thì không thể truy vấn đơn lẻ. Ngoài ra, cách khung thực thể hoạt động, nó không thành công trên các truy vấn có tính chất đệ quy. Các giải pháp duy nhất là cây traversal. –