我正在使用C#语言。我的问题是我不知道如何将检索到的分层结果集存储到我的对象中。
这是我的对象:
public class CategoryItem
{
public string Name { get; set; }
public int CategoryID { get; set; }
public int ParentID { get; set; }
public List<CategoryItem> SubCategory = new List<CategoryItem>();
public List<CategoryItem> 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<CategoryItem> items = new List<CategoryItem>();
有了这个,我可以挖掘'items'对象中的每个对象,我可以使用我的类的GetSubCategory()方法访问它的子类/子/子。这可能吗?
答案 0 :(得分:2)
如果您知道在DataSet中节点永远不会出现在其父节点之前,则可以使用此代码。在这里,当您可以查找新读取节点的父项时,可以跟踪字典中已读取的项目。如果找到父项,则将新项添加到其子项中,否则它是第一级节点。
public static List<CategoryItem> LoadFromDataSet(DataSet aDS)
{
List<CategoryItem> result = new List<CategoryItem>();
Dictionary<int, CategoryItem> alreadyRead = new Dictionary<int, CategoryItem>();
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中),则必须首先读取所有节点(并将它们放入字典中),然后循环遍历字典来构建结果。像这样:
public static List<CategoryItem> LoadFromDataSet(DataSet aDS)
{
List<CategoryItem> result = new List<CategoryItem>();
Dictionary<int, CategoryItem> alreadyRead = new Dictionary<int, CategoryItem>();
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;
}
答案 1 :(得分:0)
您必须编写递归代码才能实现此目的。
//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<Rows> 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);
}
}
}
注意:这不是完全正常工作的代码。但是,这将使您了解如何绕过并构建必须表示为对象的分层数据结构。
答案 2 :(得分:0)
将表格加载到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);
}
}