2012-05-31 2 views
3

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 서버에서 설정 데이터를 검색입니다 이

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

내 문제는 쉽게 참조 할 수

트리보기입니다

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 
방법 이 결과를 내 "CategoryItem 객체"에 저장합니까? 이걸 반복 할 필요가 없다는 단서가 없습니까? 특히 노드가 2 레벨 깊이 일 때. 는이 같은 그러한에 저장하려면이 나는 '항목'객체의 모든 객체를 발굴 할 수 있고 나는 GetSubCategory를 사용하여 하위 카테고리/아동/어린이에 액세스 할 수 있습니다와

List<CategoryItem> items = new List<CategoryItem>(); 

() 메소드 내 수업. 이것이 가능한가?

+0

왜 내 웹 응용 프로그램에 사용하기 때문에 내보기 층에 거기에 내가 통해 반복 할 수 있도록, 내가, 내보기에 "CategoryItem 목록"을 던질 계획 모든 –

+0

에 대해 하나 개의 클래스를 사용하는 "List of CategoryItem"이 접근법은 매우 일반적인 의미입니다. 즉, 계층 구조가 얼마나 깊은 지에 대한 제한이 없습니다. – chlkdst

답변

2

데이터 세트에서 노드가 부모보다 먼저 표시되지 않는다는 것을 알고 있으면이 코드를 사용할 수 있습니다. 새로 읽은 노드의 부모를 찾을 수있을 때 사전에서 이미 읽은 항목을 추적합니다. 부모를 찾으면 새 항목을 하위 항목에 추가하고, 그렇지 않으면 첫 번째 레벨 노드입니다.

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; 
    } 

내 가정이 사실이 아닌 경우 (노드가 부모 전에 데이터 집합에 표시하는 것이 가능하다 예) 먼저 모든 노드를 읽고 (그리고 사전에 넣어)해야하고 동일한 사전을 반복하여 결과를 만듭니다. 이 같은 것을 :

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; 
    } 
+0

이것은 훌륭합니다! 그것은 작동합니다! 고마워요! 너만 내 모든 업을 줄 수 있다면! 큰! 다시 한 번 감사드립니다! :디 – chlkdst

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); 
    } 
    } 
} 

참고 : 정확하게 작동하는 코드는 아닙니다. 하지만 이렇게하면 어떻게 움직이는지를 알 수 있고 객체로 표현되어야하는 계층 적 데이터 구조를 만들 수 있습니다.

0

은 데이터 테이블에 테이블을로드하고 주먹, 방법은 아래

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

변화를 루트 노드를 찾아 당신이 하위 카테고리를 추가하는 재귀 적 메소드를 호출 할 필요가 그런 루트 개체

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() }; 

를 만들 당신이 원하는대로.

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); 
    } 
} 
관련 문제