簡體   English   中英

創建分層類結構,循環遍歷數據表,然后添加父和子以及返回對象

[英]Create hierarchical class structure , loop through data table and then add parent and child and return object

我想創建一個類結構,它可以表示以下所有相同類型的對象的heirarchichal結構

-Parent1
- - Child1 
- - - ChildA of Child1
- - - ChildB of Child1
- - Child2 
- - - ChildA of Child2
- - - ChildB of Child2
- Parent2

數據表行具有ID,ParentID,名稱和級別

父級為0,子級為1,ChildA為2,依此類推

我能夠將數據從數據庫返回到數據表,但是在創建類結構然后填充對象的任何幫助之后我都會非常感激

以下是使用LINQ如何執行此操作的示例。 首先是一個樣本數據表。 我假設頂級項目的父ID為0。

var dataTable = new DataTable();
dataTable.Columns.Add("Id", typeof(Int32));
dataTable.Columns.Add("ParentId", typeof(Int32));
dataTable.Columns.Add("Name", typeof(String));
dataTable.Rows.Add(new Object[] { 1, 0, "A" });
dataTable.Rows.Add(new Object[] { 2, 1, "B" });
dataTable.Rows.Add(new Object[] { 3, 1, "C" });
dataTable.Rows.Add(new Object[] { 4, 0, "D" });
dataTable.Rows.Add(new Object[] { 5, 4, "E" });

表示每個數據項的類:

class Item {

  public Int32 Id { get; set; }

  public String Name { get; set; }

  public IEnumerable<Item> Children { get; set; }

}

獲取特定項目的子項的函數:

IEnumerable<DataRow> GetChildren(DataTable dataTable, Int32 parentId) {
  return dataTable
    .Rows
    .Cast<DataRow>()
    .Where(row => row.Field<Int32>("ParentId") == parentId);
}

用於創建包括子集合的項的函數。 此函數將遞歸層次結構:

Item CreateItem(DataTable dataTable, DataRow row) {
  var id = row.Field<Int32>("Id");
  var name = row.Field<String>("Name");
  var children = GetChildren(dataTable, id)
    .Select(r => CreateItem(dataTable, r))
    .ToList();
  return new Item { Id = id, Name = name, Children = children };
}

獲取頂級項目行的函數:

IEnumerable<DataRow> GetTopLevelRows(DataTable dataTable) {
  return dataTable
    .Rows
    .Cast<DataRow>()
    .Where(row => row.Field<Int32>("ParentId") == 0);
}

把它們放在一起:

var items = GetTopLevelRows(dataTable)
  .Select(row => CreateItem(dataTable, row))
  .ToList();

鑒於上述信息,您可以只使用一個類來完成此操作。

public class MyItem
{
  public IList<MyItem> ChildItems{get;set;}
}

在這里你基本上得到了一個對象,它可以包含一個自己類型的集合作為子對象,因此,這些子對象也可以包含MyItem的集合作為子子對象。

考慮以下:

var parentItem = new MyItem()
var childItem = new MyItem();
var childChildItem = new MyItem();

childItem.ChildItems.Add(childChildItem);
parentItem.ChildItems.Add(childItem);

有更好的方法可以對項目的添加進行編碼,但這樣可以在邏輯上將其分解為足以使概念清晰明了。

這是我的方法。

從問題中定義的數據開始:

var dataTable = new DataTable();
dataTable.Columns.Add("Id", typeof(int));
dataTable.Columns.Add("ParentId", typeof(int));
dataTable.Columns.Add("Name", typeof(String));
dataTable.Rows.Add(new Object[] { 1, 0, "Parent1" });
dataTable.Rows.Add(new Object[] { 2, 1, "Child1" });
dataTable.Rows.Add(new Object[] { 3, 2, "ChildA of Child1" });
dataTable.Rows.Add(new Object[] { 4, 2, "ChildB of Child1" });
dataTable.Rows.Add(new Object[] { 5, 1, "Child2" });
dataTable.Rows.Add(new Object[] { 6, 5, "ChildA of Child2" });
dataTable.Rows.Add(new Object[] { 7, 5, "ChildB of Child2" });  
dataTable.Rows.Add(new Object[] { 8, 0, "Parent2" });

然后就這樣做:

var lookup = dataTable.Rows.Cast<DataRow>().ToLookup(x => x.Field<int>("ParentId"));

Func<int, Item[]> build = null;
build = n =>
    lookup[n]
        .Select(dr => new Item()
            {
                Id = dr.Field<int>("Id"),
                Name = dr.Field<string>("Name"),
                Children = build(dr.Field<int>("Id")),
            })
            .ToArray();

var items = build(0);

這給了:

項目

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM