前两天我们介绍了一种新的存储无限级分类方法,但是读出分类的时候怎么实现树形显示呢?方法很简单,我们自己定义一个树形的数据结构,然后根据数据库存储的节点的深度来插入到树里面,当然显示的时候需要用递归来显示一下,不过这里的递归只是在内存里面递归,效率是相当高的。

2008-11-17 更新为不使用树结构,使用排序和深度来做文章。

在数据库读出数据的时候直接按照 LID 来进行 ASC 排序就可以了,默认的排列顺序就是按照树走的,大家可以插入一些数据,并读取一下就可以很明了的看到顺序了,插入树循环的时候只需要对深度进行运算就可以了。

下面我只写出了一些关键地方的代码,具体的代码自己试着多写写在纸上多画画应该就明白了。

另外就是想说下,这种分类算法只适用于一般的树形分类,并不适用于插入数据比较频繁的树形结构,比如说无限次回复的评论,无限次回复的评论有另外一种更适合的算法。

新的方法

  1. Response.Write("<ul id=\"ZoneTree\" class=\"tree\">");  
  2. Response.Write("<li id=\"zv_0\"><a class=\"add\" href=\"javascript:ZonePost(1,0);\" title=\"增加根区域\">增加根区域</a><div id=\"zn_0\"></div></li>");  
  3.  
  4. ZoneList oZoneList = SiteLoad.ZoneList;  
  5. ZoneItem oZoneItem;  
  6. Int32 intDee = 1, intNum = oZoneList.Count;  
  7.  
  8. for (Int32 intI = 0; intI < intNum; intI++)  
  9. {  
  10.     oZoneItem = oZoneList[intI];  
  11.  
  12.     if (intI != 0 && oZoneItem.Tree == intDee)  
  13.     {  
  14.         Response.Write("</li>");  
  15.     }  
  16.     else if (oZoneItem.Tree > intDee)  
  17.     {  
  18.         Response.Write("<ul>");  
  19.     }  
  20.     else if (oZoneItem.Tree < intDee)  
  21.     {  
  22.         Response.Write(SiteFun.EchoText("</li></ul>", intDee - oZoneItem.Tree));  
  23.     }  
  24.  
  25.     Response.Write(String.Format("<li id=\"zv_{0}\"><span id=\"zName_{0}\">{1}</span>", oZoneItem.ID, oZoneItem.Name));  
  26.  
  27.     intDee = oZoneItem.Tree;  
  28.  
  29. }  
  30. Response.Write(SiteFun.EchoText("</li></ul>", intDee - 1));  
  31. Response.Write("</ul>"); 

旧的树结构方法

首先我们定义一个树形的数据结构:

  1. public class ZoneList  
  2. {  
  3.     private readonly ZoneList _Parent = null;  
  4.     private readonly List<ZoneList> _Childs = new List<ZoneList>();  
  5.     private readonly ZoneItem _Value = null;  
  6.  
  7.     public ZoneList Parent { get { return _Parent; } }  
  8.  
  9.     public List<ZoneList> Childs { get { return _Childs; } }  
  10.  
  11.     public ZoneItem Value { get { return _Value; } }  
  12.  
  13.     public ZoneList Root  
  14.     {  
  15.         get 
  16.         {  
  17.             ZoneList curNode = this;  
  18.             while (curNode.Parent != null)  
  19.             {  
  20.                 curNode = curNode.Parent;  
  21.             }  
  22.             return curNode;  
  23.         }  
  24.     }  
  25.  
  26.     public ZoneList() { }  
  27.  
  28.     public ZoneList(ZoneItem value, ZoneList parent)  
  29.     {  
  30.         _Value = value;  
  31.         _Parent = parent;  
  32.     }  
  33.  
  34.     public ZoneList AddChild(ZoneItem value)  
  35.     {  
  36.         ZoneList nZoneList = new ZoneList(value, this);  
  37.         _Childs.Add(nZoneList);  
  38.         return nZoneList;  
  39.     }  

然后读取数据库并插入到树:

  1. public ZoneList Select()  
  2. {  
  3.     ZoneList oZoneList = new ZoneList();  
  4.     ZoneItem oZoneItem;  
  5.  
  6.     Int32 intDee = 0;  
  7.  
  8.     SqlDataReader oData = SiteSQL.ExecuteReader("ZoneSelect");  
  9.     while (oData.Read())  
  10.     {  
  11.         oZoneItem = new ZoneItem();  
  12.         oZoneItem.ID = oData.GetInt32(0);  
  13.         oZoneItem.Tree = oData.GetInt32(1);  
  14.         oZoneItem.Name = oData.GetString(2);  
  15.         intDee = intDee - oZoneItem.Tree;  
  16.  
  17.         for (Int32 intI = 0; intI <= intDee; intI++)  
  18.         {  
  19.             oZoneList = oZoneList.Parent;  
  20.         }  
  21.  
  22.         oZoneList = oZoneList.AddChild(oZoneItem);  
  23.  
  24.         intDee = oZoneItem.Tree;  
  25.     }  
  26.     oData.Close();  
  27.     return oZoneList.Root;  

显示的时候直接用递归就可以了:

  1. private void ZoneOutWrite(ZoneList oZoneList)  
  2. {  
  3.     foreach (ZoneList oZoneNode in oZoneList.Childs)  
  4.     {  
  5.         Response.Write(String.Format("<li id=\"zv_{0}\"><span id=\"zName_{0}\">{1}</span>", oZoneNode.Value.ID, oZoneNode.Value.Name));  
  6.  
  7.         if (oZoneNode.Childs.Count > 0)  
  8.         {  
  9.             Response.Write("<ul>");  
  10.             ZoneOutWrite(oZoneNode);  
  11.             Response.Write("</ul>");  
  12.         }  
  13.         Response.Write("</li>");  
  14.     }  
此文章由 Loveyuki 于 2008-11-17 16:15 编辑

本日志由 Loveyuki 于 2008-11-15 18:43 发表,目前已经被浏览 3200 次,评论 3 次;

作者添加了以下标签: SQL Server无限级分类树型显示

引用通告:http://blog.loveyuki.com/Article/105/Trackback.ashx

评论订阅:http://blog.loveyuki.com/Article/105/Feeds.ashx

评论列表

  1. 2008-11-16 19:26 | # | 回复
    也可以不用递归。就是循环,Tree > PrevTree 就加个 <ul> Tree< PrevTree 就加 PrevTree - Tree 个</ul> 也可以。嘎嘎。当时思维对这个加减 UL 比较混乱就导出成树形了哦。
  2. 2008-11-16 20:13 | # | 回复
    问一个问题,你估计农业信息 还有 农业 这两个关键字你估计排到前面问题大不大?你看一下,我感觉竞争不是很厉害,你估计如何?
  3. 21pt.com   2008-11-17 08:50
    [转]把SQL Server存储的层级数据读出成树显示: 前两天我们介绍了一种新的存储无限级分类方法,但是读出分类的时候怎么实现树形显示呢?方法很简单,我们自己定义一个树形的数据结构,然后根据数据库存储的节点的深度来插入到树里面,当然显示的时候需要用递归来显示一下,不过这里...
(必填)
(必填,不会被公开)