树状显示Web系统中的分类

在Web系统中经常会碰到分类:新闻分类、产品分类,在更新分类、添加新闻/产品时避免不了要树状来显示分类:



经典的数据库表结构设计如下图:



通常是写一个函数使用递归将其显示到界面上,但应对众多的显示方式似乎有些力不从心。翻看Dvbbs.DotNet 1.0.5源码得到了一些思路,新建一个字段OrderId,它表示菜单显示的位置:



显示的时候就非常方便了,只需OrderId按升序排列即可:

Select [Id],ClassName,ParentId,OrderId,Depth From NewsClass order By orderId
结果集:


下边是更新OrderId的代码:

/// <summary>
/// 更新OrderId字段
/// </summary>
/// <param name="parentId"></param>
/// <param name="maxOrderId"></param>
/// <remarks>
/// 使用说明(添加、修改、删除分类时调用一次):
///     int parentId = 0;
///     int maxOrderId = 1;
///     UpdateOrderId(parentId, ref maxOrderId);
/// </remarks>
protected void UpdateOrderId(int parentId, ref int maxOrderId)
{
    using (SqlConnection conn = new SqlConnection("server=(local);uid=sa;pwd=sa;database=MzwuCom;"))
    {
        conn.Open();

        SqlDataAdapter da = new SqlDataAdapter(string.Format("Select Id,ClassName,ParentId,OrderId From NewsClass Where ParentId='{0}' order By Id", parentId.ToString()), conn);
        DataTable dt = new DataTable();
        da.Fill(dt);
        for (int i = 0; i < dt.Rows.Count; i++)
        {
            //Response.Write(dt.Rows[i]["id"] + "," + dt.Rows[i]["parentid"] + "," + dt.Rows[i]["orderid"] + "," + dt.Rows[i]["classname"] + "<br/>");

            SqlCommand cmd = new SqlCommand();
            cmd.Connection = conn;
            cmd.CommandType = CommandType.Text;
            cmd.CommandText = "Update NewsClass Set orderId=@OrderId Where Id=@Id";
            cmd.Parameters.Add(new SqlParameter("@OrderId", maxOrderId.ToString()));
            cmd.Parameters.Add(new SqlParameter("@Id", dt.Rows[i]["id"].ToString()));
            cmd.ExecuteNonQuery();
            maxOrderId++;
            UpdateOrderId(Convert.ToInt32(dt.Rows[i]["id"]), ref maxOrderId);
        }
        conn.Close();
    }
}

树状菜单显示的时候通常是需要按级数缩进的,权使用上边几个字段很难控制缩进,所以我们得再引入一个字段Depth,表示菜单的级数:

Select [Id],SPACE(Depth) + '├' + ClassName ClassName,ParentId,OrderId,Depth From NewsClass order By orderId
结果集:


更新Depth的代码:

/// <summary>
/// 更新Depth字段
/// </summary>
/// <param name="parentId"></param>
/// <param name="maxDepth"></param>
/// <remarks>
/// 使用说明(添加、修改、删除分类时调用一次):
///     int parentId = 0;
///     int maxDepth = 1;
///     UpdateDepth(parentId, maxDepth);
/// </remarks>
protected void UpdateDepth(int parentId, int maxDepth)
{
    using (SqlConnection conn = new SqlConnection("server=(local);uid=sa;pwd=sa;database=MzwuCom;"))
    {
        conn.Open();

        SqlDataAdapter da = new SqlDataAdapter(string.Format("Select Id,ClassName,ParentId,OrderId,Depth From NewsClass Where ParentId='{0}' order By Id", parentId.ToString()), conn);
        DataTable dt = new DataTable();
        da.Fill(dt);
        for (int i = 0; i < dt.Rows.Count; i++)
        {
            SqlCommand cmd = new SqlCommand();
            cmd.Connection = conn;
            cmd.CommandType = CommandType.Text;
            cmd.CommandText = "Update NewsClass Set Depth=@Depth Where Id=@Id";
            cmd.Parameters.Add(new SqlParameter("@Depth", maxDepth.ToString()));
            cmd.Parameters.Add(new SqlParameter("@Id", dt.Rows[i]["id"].ToString()));
            cmd.ExecuteNonQuery();
            UpdateDepth(Convert.ToInt32(dt.Rows[i]["id"]), maxDepth + 1);
        }
        conn.Close();
    }
}

OK,合并一下上边两个函数:

/// <summary>
/// 更新OrderId和Depth字段
/// </summary>
/// <param name="parentId"></param>
/// <param name="maxOrderId"></param>
/// <param name="maxDepth"></param>
/// 使用说明(添加、修改、删除分类时调用一次):
///     int parentId = 0;
///     int maxOrderId = 1;
///     int maxDepth = 1;
///     UpdateOrderIdAndDepth(parentId,ref maxOrderId, maxDepth);
/// </remarks>
protected void UpdateOrderIdAndDepth(int parentId, ref int maxOrderId, int maxDepth)
{
    using (SqlConnection conn = new SqlConnection("server=(local);uid=sa;pwd=sa;database=MzwuCom;"))
    {
        conn.Open();

        SqlDataAdapter da = new SqlDataAdapter(string.Format("Select Id,ClassName,ParentId,OrderId From NewsClass Where ParentId='{0}' order By Id", parentId.ToString()), conn);
        DataTable dt = new DataTable();
        da.Fill(dt);
        for (int i = 0; i < dt.Rows.Count; i++)
        {
            SqlCommand cmd = new SqlCommand();
            cmd.Connection = conn;
            cmd.CommandType = CommandType.Text;
            cmd.CommandText = "Update NewsClass Set orderId=@OrderId,Depth=@Depth Where Id=@Id";
            cmd.Parameters.Add(new SqlParameter("@OrderId", maxOrderId.ToString()));
            cmd.Parameters.Add(new SqlParameter("@Depth", maxDepth.ToString()));
            cmd.Parameters.Add(new SqlParameter("@Id", dt.Rows[i]["id"].ToString()));
            cmd.ExecuteNonQuery();
            maxOrderId++;
            UpdateOrderIdAndDepth(Convert.ToInt32(dt.Rows[i]["id"]), ref maxOrderId, maxDepth + 1);
        }
        conn.Close();
    }
}


评论: 0 | 引用: 0 | 查看次数: 3676
发表评论
登录后再发表评论!