asp/asp.net中遍历树型结构.

据库:SqlServer2000
:tree
表结构


测试数据


算法:使用递归实现

======================================
asp代码

< %@ Language  =  VBScript% >
< % Option   Explicit % >
< %
Dim  oConn, sSql
Call  DBConnBegin()

Dim  sTableName
Dim  nCurrent, nLen, aTree() 
sTableName 
=   " tree "
nCurrent 
=   1
nLen 
=  GetRescordCount()

ReDim  aTree(nLen)

Call  GetPowerName( 0 )
' Dim i
'
For i = 1 To nLen
     ' Response.Write aTree(i) & "<br>"
'
Next
Call  DBConnEnd()

Function   GetRescordCount()
    GetRescordCount 
=  oConn.Execute( " select count(id) from  "   &  sTableName)( 0 )
End Function

Sub  GetPowerName(s_Id)
    
Dim  n_ParentId, j, oRs
    
Set  oRs  =  Server.CreateObject(  " ADODB.Recordset "  )
    sSql 
=   " select id,PowerName,Layer from  "   &  sTableName  &   "  where ParentId= "   &  s_Id
    oRs.Open sSql, oConn, 
0 1
    
Do   While   Not  oRs.Eof
        
For  j  =   1   To  oRs( " Layer " )
            response.write 
" &nbsp;&nbsp;&nbsp;&nbsp; "
        
Next
        aTree(nCurrent) 
=  oRs( " PowerName " )
        response.write aTree(nCurrent) 
&   " <br> "
        nCurrent 
=  nCurrent  +   1
        n_ParentId 
=  oRs( " id " )
        
Call  GetPowerName(n_ParentId)
        oRs.MoveNext
    
Loop
    oRs.Close
    
Set  oRs  =   Nothing
End Sub

Sub  DBConnBegin()
    
'  如果数据库对象已打开,不要再打开
     If   IsObject (oConn)  =   True   Then   Exit   Sub

    
'  你可以不需要打开数据库连接对象而直接打开记录集对象,但如果你需要打开多个记录集对象的话,效率是很低的。
     '  如果你不创建一个数据库连接对象,ADO会在每个记录集打开时自动创建一个新的数据库连接对象,就算你用的是相同的SQL语句。
     Set  oConn  =  Server.CreateObject( " ADODB.Connection " )

    
On   Error   Resume   Next

    
' Provider=SQLOLEDB.1;Server=(local);Initial Catalog =cx_soft;Integrated Security=SSPI;
     ' Provider=SQLOLEDB.1;Server=(local);Initial Catalog =cx_soft;Trusted_Connection=yes;
    oConn.Open  " Provider=sqloledb.1;Data Source=(local);Initial Catalog=AspNetTest;User Id=sa;Password=; "
    
    
If  Err.Number  >   0   Then
        
'  完全地退出正在运行的脚本
        Response.End
    
End   If

    
'  创建一个记录集
    
End Sub

Sub  DBConnEnd()
    
On   Error   Resume   Next
    oRs.Close
    
Set  oRs  =   Nothing
    oConn.Close
    
Set  oConn  =   Nothing
End Sub
%
>



asp.net代码
( 请注意:asp.net1.1中用同一个Connection,在前一个DataReader没有Close情况下再创建DataReader会出现错误提示:已有打开的与此连接相关联的 DataReader,必须首先将它关闭
我的做法是每次都创建一个Connection,很浪费资源,不知道有没其他好办法.
)
  1 using  System;
  2 using  System.Collections;
  3 using  System.ComponentModel;
  4 using  System.Data;
  5 using  System.Drawing;
  6 using  System.Web;
  7 using  System.Web.SessionState;
  8 using  System.Web.UI;
  9 using  System.Web.UI.WebControls;
 10 using  System.Web.UI.HtmlControls;
 11 using  System.Data.SqlClient;
 12
 13 namespace  AspNetTest.Common
 14 {
 15    /**//// <summary>
 16    /// tree 的摘要说明。
 17    /// </summary>

 18
 19    public class tree : System.Web.UI.Page
 20    {
 21        private string tablename = "tree";
 22        int current = 0;
 23        int len = 0;
 24        string[] arrPowerName;
 25        string ConnectionString;
 26        public tree()
 27        {
 28            ConnectionString = System.Configuration.ConfigurationSettings.AppSettings["ConnectionString"];
 29            len = GetRecordCount();
 30            arrPowerName = new string[len];
 31        }

 32        private void Page_Load(object sender, System.EventArgs e)
 33        {
 34            
 35            GetPowerName(0);
 36            //CloseDbConnection();
 37            //ResponseArray();
 38            // 在此处放置用户代码以初始化页面
 39        }

 40        private void GetPowerName(int _ParentId)
 41        {
 42            int Id;
 43            string PowerName;
 44            string sql = "select Id,PowerName,Layer from " + tablename + " where ParentId=" + _ParentId;
 45            try
 46            {
 47                SqlConnection conn = new SqlConnection(ConnectionString);
 48                conn.Open();
 49                SqlCommand cmd = new SqlCommand(sql, conn);
 50                SqlDataReader dr = cmd.ExecuteReader();
 51                while(dr.Read())
 52                {    
 53                    for(int j=0; j<int.Parse(dr["Layer"].ToString()); j++)
 54                    {
 55                        Response.Write("&nbsp;&nbsp;&nbsp;&nbsp;");
 56                    }

 57                    PowerName = dr["PowerName"].ToString();
 58                    Response.Write(PowerName + "<br>");
 59                    arrPowerName[current++= PowerName;
 60                    Id = int.Parse(dr["Id"].ToString());
 61                    GetPowerName(Id);
 62                }

 63                dr.Close();
 64                conn.Close();
 65            }

 66            catch(Exception ex)
 67            {
 68                Response.Write(ex.ToString());
 69            }

 70        }

 71        private void ResponseArray()
 72        {
 73            int i;
 74            for(i=0; i<len; i++)
 75            {
 76                Response.Write(arrPowerName[i] + "<br>");
 77            }

 78        }

 79        private void CloseDbConnection()
 80        {
 81            //conn.Close();
 82        }

 83        private int GetRecordCount()
 84        {
 85            SqlConnection conn = new SqlConnection(ConnectionString);
 86            string sql = "select count(id) from " + tablename;
 87            conn.Open();
 88            SqlCommand cmd = new SqlCommand(sql, conn);
 89            int count = int.Parse(cmd.ExecuteScalar().ToString());
 90            conn.Close();
 91            return count;
 92        }

 93        
 94        Web 窗体设计器生成的代码#region Web 窗体设计器生成的代码
 95        override protected void OnInit(EventArgs e)
 96        {
 97            //
 98            // CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。
 99            //
100            InitializeComponent();
101            base.OnInit(e);
102        }

103        
104        /**//// <summary>
105        /// 设计器支持所需的方法 - 不要使用代码编辑器修改
106        /// 此方法的内容。
107        /// </summary>

108        private void InitializeComponent()
109        {    
110            this.Load += new System.EventHandler(this.Page_Load);
111
112        }

113        #endregion

114    }

115}

116



遍历结果:





代码下载:

asp代码: /Files/jiny-z/tree(asp).rar
asp.net代码: /Files/jiny-z/tree(asp.net).rar



*********************************************************
根据chill ,flower.b的提示,修改了代码。
原来:asp/asp.net代码中都是在数据集中循环,效率较低.。
现在:asp代码改为在数组中循环,asp.net代码改为在DataTable中循环。
*********************************************************

asp代码:
< %@ Language  =  VBScript% >
< % Option   Explicit % >
< %
Dim  oConn, oRs, sSql
Dim  aTree
Call  FillArrayFromRs()
Call  blTreeArray( 0 )

Sub  FillArrayFromRs()
    
Dim  s_TableName
    s_TableName 
=   " tree "
    
Call  DBConnBegin()
    
Set  oRs  =  Server.CreateObject(  " ADODB.Recordset "  )
    sSql 
=   " select Id,PowerName,Layer,ParentId from  "   &  s_TableName
    oRs.Open sSql, oConn, 
0 1
    aTree 
=  oRs.GetRows()
    
' response.write ubound(aTree, 2)
    oRs.Close
    
Call  DBConnEnd()
End Sub

Sub  blTreeArray(n_ParentId)
    
Dim  row, rows
    
Dim  n_NextParentId
    
Dim  n_Space
    rows 
=   UBound (aTree,  2 )
    
for  row  =   0   To  rows
        
If  aTree( 3 , row)  =  n_ParentId  Then
            
for  n_Space  =   1   To  aTree( 2 , row)
                Response.Write 
" &nbsp;&nbsp;&nbsp;&nbsp; "
            
Next
            Response.Write aTree(
1 , row)  &   " <br> "
            n_NextParentId 
=  aTree( 0 , row)
            blTreeArray(n_NextParentId)
        
End   If
    
Next
End Sub


Sub  DBConnBegin()
    
'  如果数据库对象已打开,不要再打开
     If   IsObject (oConn)  =   True   Then   Exit   Sub

    
'  你可以不需要打开数据库连接对象而直接打开记录集对象,但如果你需要打开多个记录集对象的话,效率是很低的。
     '  如果你不创建一个数据库连接对象,ADO会在每个记录集打开时自动创建一个新的数据库连接对象,就算你用的是相同的SQL语句。
     Set  oConn  =  Server.CreateObject( " ADODB.Connection " )

    
On   Error   Resume   Next

    
' Provider=SQLOLEDB.1;Server=(local);Initial Catalog =cx_soft;Integrated Security=SSPI;
     ' Provider=SQLOLEDB.1;Server=(local);Initial Catalog =cx_soft;Trusted_Connection=yes;
    oConn.Open  " Provider=sqloledb.1;Data Source=(local);Initial Catalog=AspNetTest;User Id=sa;Password=; "
    
    
If  Err.Number  >   0   Then
        
'  完全地退出正在运行的脚本
        Response.End
    
End   If

    
'  创建一个记录集
    
End Sub

Sub  DBConnEnd()
    
On   Error   Resume   Next
    oRs.Close
    
Set  oRs  =   Nothing
    oConn.Close
    
Set  oConn  =   Nothing
End Sub




%
>

asp.net代码:

using  System;
using  System.Collections;
using  System.ComponentModel;
using  System.Data;
using  System.Data.SqlClient;
using  System.Drawing;
using  System.Web;
using  System.Web.SessionState;
using  System.Web.UI;
using  System.Web.UI.WebControls;
using  System.Web.UI.HtmlControls;

namespace  AspNetTest.Common
{
    
/**//// <summary>
    
/// tree_DataTable 的摘要说明。
    
/// </summary>

     
    
public class tree_DataTable : System.Web.UI.Page
    
{
        
private DataTable dtPowerTree = new DataTable();
        
const string tablename = "tree";
        
private void Page_Load(object sender, System.EventArgs e)
        
{
            FillTreeDataTable();
            blTreeDataTable(
0);
            dtPowerTree.Clear();            
            
// 在此处放置用户代码以初始化页面
        }

        
private void FillTreeDataTable()
        
{
            
string ConnectionString = System.Configuration.ConfigurationSettings.AppSettings["ConnectionString"];
            SqlConnection conn 
= new SqlConnection(ConnectionString);
            SqlDataAdapter da 
= new SqlDataAdapter("select Id,PowerName,Layer,ParentId from " + tablename, conn);
            da.Fill(dtPowerTree);
        }

        
private void blTreeDataTable(int _ParentId)
        
{
            
string filter = "ParentId=" + _ParentId;
            
string sort = "Id ASC";
            DataRow[] drs 
= dtPowerTree.Select(filter, sort);
            
for(int i=0; i<drs.Length; i++)
            
{
                
if(Convert.ToInt32(drs[i][3]) == _ParentId)
                
{
                    
int Id = Convert.ToInt32(drs[i][0]);
                    
string PowerName = drs[i][1].ToString();
                    
int Layer = Convert.ToInt32(drs[i][2]);
                    
for(int space=1; space<=Layer; space++)
                    
{
                        Page.Response.Write(
"&nbsp;&nbsp;&nbsp;&nbsp;");
                    }

                    Page.Response.Write(PowerName 
+ "<br>");
                    blTreeDataTable(Id);
                }

            }

        }

        
Web 窗体设计器生成的代码#region Web 窗体设计器生成的代码
        
override protected void OnInit(EventArgs e)
        
{
            
//
            
// CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。
            
//
            InitializeComponent();
            
base.OnInit(e);
        }

        
        
/**//// <summary>
        
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
        
/// 此方法的内容。
        
/// </summary>

        private void InitializeComponent()
        
{    
            
this.Load += new System.EventHandler(this.Page_Load);

        }

        
#endregion

    }

}

转载于:https://www.cnblogs.com/tonyman/archive/2007/02/13/648985.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值