不错呦!smile@林凯西,确保“准备文件”中的几个文件都有安装,S...您好,看了您这篇帖子觉得很有帮助。但是有个问题想请...我的修改过了怎么还被恶意注册呢 @jjjjiiii 用PJ快9年了,主要是A...PJ3啊,貌似很少有人用PJ了,现在不是WP就是z...@332347365,我当时接入时错误码没有-10...楼主,ChkValue值应为-103是什么意思呢?...大哥 你最近能看到我发的信息,请跟我联系,我有个制...
树状显示Web系统中的分类
编辑:dnawo 日期:2008-09-21
在Web系统中经常会碰到分类:新闻分类、产品分类,在更新分类、添加新闻/产品时避免不了要树状来显示分类:

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

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

显示的时候就非常方便了,只需OrderId按升序排列即可:
Select [Id],ClassName,ParentId,OrderId,Depth From NewsClass order By orderId
结果集:

下边是更新OrderId的代码:
树状菜单显示的时候通常是需要按级数缩进的,权使用上边几个字段很难控制缩进,所以我们得再引入一个字段Depth,表示菜单的级数:
Select [Id],SPACE(Depth) + '├' + ClassName ClassName,ParentId,OrderId,Depth From NewsClass order By orderId
结果集:

更新Depth的代码:
OK,合并一下上边两个函数:

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

通常是写一个函数使用递归将其显示到界面上,但应对众多的显示方式似乎有些力不从心。翻看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();
}
}
/// 更新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();
}
}
/// 更新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();
}
}
/// 更新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
发表评论
请登录后再发表评论!