如何使用检索到的分层结果集创建对象?

我正在使用C#语言。 我的问题是我不知道如何将检索到的分层结果集存储到我的对象。

这是我的对象:

public class CategoryItem { public string Name { get; set; } public int CategoryID { get; set; } public int ParentID { get; set; } public List SubCategory = new List(); public List GetSubCategory() { return SubCategory; } public void AddSubCategory(CategoryItem ci) { SubCategory.Add(ci); } public void RemoveSubCategory(CategoryItem ci) { for (int i = 0; i < SubCategory.Count; i++) { if (SubCategory.ElementAt(i).CategoryID == ci.CategoryID) { SubCategory.RemoveAt(i); break; } } } } 

这是我从MSSQL服务器检索数据集的示例

 ID PrntID Title _______ _______ 1 0 Node1 2 1 Node2 3 1 Node3 4 2 Node4 5 2 Node5 6 2 Node6 7 3 Node7 8 4 Node8 9 4 Node9 10 9 Node10 

树视图,方便参考

 Node 1 -Node 2 --Node 4 ---Node 8 ---Node 9 ----Node 10 --Node 5 --Node 6 -Node 3 --Node 7 

我的问题是如何将此结果存储到我的“CategoryItem对象”。 我没有任何线索我需要使用迭代吗? 特别是当节点是2级深度时。 我想把它存储在这样的:

 List items = new List(); 

有了这个我可以挖掘’items’对象中的每个对象,我可以使用我的类的GetSubCategory()方法访问它的子类/子/子。 这可能吗?

如果您知道在DataSet中节点永远不会出现在其父节点之前,则可以使用此代码。 在这里,您可以在查找新读取节点的父项时跟踪字典中已读取的项目。 如果找到父项,则将新项添加到其子项中,否则它是第一级节点。

  public static List LoadFromDataSet(DataSet aDS) { List result = new List(); Dictionary alreadyRead = new Dictionary(); foreach (DataRow aRow in aDS.Tables["YourTable"].Rows) { CategoryItem newItem = new CategoryItem(); newItem.CategoryID = (int)aRow["ID"]; newItem.ParentID = (int)aRow["PrntID"]; newItem.Name = (string)aRow["Title"]; alreadyRead[newItem.CategoryID] = newItem; CategoryItem aParent; if (alreadyRead.TryGetValue(newItem.ParentID, out aParent)) aParent.AddSubCategory(newItem); else result.Add(newItem); } return result; } 

如果我的假设不正确(即节点可能在其父节点之前出现在DataSet中),则必须首先读取所有节点(并将它们放在Dictionary中),然后循环遍历相同的Dictionary来构建结果。 像这样的东西:

  public static List LoadFromDataSet(DataSet aDS) { List result = new List(); Dictionary alreadyRead = new Dictionary(); foreach (DataRow aRow in aDS.Tables["YourTable"].Rows) { CategoryItem newItem = new CategoryItem(); newItem.CategoryID = (int)aRow["ID"]; newItem.ParentID = (int)aRow["PrntID"]; newItem.Name = (string)aRow["Title"]; alreadyRead[newItem.CategoryID] = newItem; } foreach (CategoryItem newItem in alreadyRead.Values) { CategoryItem aParent; if (alreadyRead.TryGetValue(newItem.ParentID, out aParent)) aParent.AddSubCategory(newItem); else result.Add(newItem); } return result; } 

您必须编写递归代码才能实现此目的。

 //First of all, find the root level parent int baseParent = "0"; // Find the lowest root parent value foreach (var selection in collection) { //assign any random parent id, if not assigned before if (string.IsNullOrEmpty(baseParent)) baseParent = selection["PrntID"]; //check whether it is the minimum value if (Convert.ToInt32(selection["PrntID"]) < Convert.ToInt32(baseParent)) baseParent = selection["PrntID"]; } //If you are sure that your parent root level node would always be zero, then you could //probably skip the above part. //Now start building your hierarchy foreach (var selection in collection) { CategoryItem item = new CategoryItem(); //start from root if(selection["Id"] == baseParentId) { //add item property item.Id = selection["id]; //go recursive to bring all children //get all children GetAllChildren(item , collection); } } private void GetAllChildren(CategoryItem parent, List Collection) { foreach(var selection in Collection) { //find all children of that parent if(selection["PrntID"] = parent.Id) { CategoryItem child = new CategoryItem (); //set properties child.Id = selection["Id"]; //add the child to the parent parent.AddSubCategory(child); //go recursive and find all child for this node now GetAllChildren(child, Collection); } } } 

注意:这不是完全正常工作的代码。 但是,这将使您了解如何绕过并构建必须表示为对象的分层数据结构。

将表加载到Datatable中,然后找到根节点并创建根对象

 DataRow[] rootRow = table.Select("PrntID = 0"); CategoryItem root = new CategoryItem() { CategoryID = (int)rootRow[0]["ID"].ToString(), Name = rootRow[0]["Title"].ToString(), ParentID = (int)rootRow[0]["PrntID"].ToString() }; 

然后你需要调用递归方法来添加子类别,

 GetCategoryItem((int)rootRow[0]["ID"].ToString(), root); 

根据需要更改以下方法。

 public void GetCategoryItem(CategoryItem parant) { DataRow[] rootRow = table.Select("PrntID =" + parant.CategoryID); for (int i = 0; i < rootRow.Length; i++) { CategoryItem child = new CategoryItem() { CategoryID = (int)rootRow[i]["ID"].ToString(), Name = rootRow[i]["Title"].ToString(), ParentID = (int)rootRow[i]["PrntID"].ToString() }; GetCategoryItem(child); parant.SubCategory.Add(child); } }