树形结构应用技巧

有时候在项目中我们会碰到这样的场景:

 员工部门我们一般都在数据库里面存成树形结构,用的时候根据递归来加载整个部门的架构,员工存储在相应的部门,如果要获取某些部门下面的员工的时候

,我们一般的做法是根据部门id 递归找到相应的树,然后记下部门的id,然后过滤找到员工的列表。

我们的做法是在表中添加一个path,该字段存的是每个节点相对根节点的路径用|隔开,比如 TXCB|UTSD|JKDF,

那么对上述的情景的时候我们只要找到要查找的节点的path,然后用一条like 语句就很容易实现上述功能。

表结构

View Code
CREATE TABLE [dbo].[scs_sh_job](
[Id] [int] IDENTITY(1,1) NOT NULL, --自增id
[code] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NULL, 编码
[father_jobId] [uniqueidentifier] NULL, 父id
[father_job_name] [nvarchar](100) COLLATE Chinese_PRC_CI_AS NULL, --父名称
[job_id] [uniqueidentifier] NULL, -子id
[job_name] [nvarchar](100) COLLATE Chinese_PRC_CI_AS NULL, --子名称
[job_path] [nvarchar](100) COLLATE Chinese_PRC_CI_AS NULL, -- 父路径+“|”+ code
[u_uid] [uniqueidentifier] NULL, --添加人id
[u_uname] [char](10) COLLATE Chinese_PRC_CI_AS NULL, --添加人姓名
[u_time] [datetime] NULL --添加时间
) ON [DATA]

  我们用treeview控件来演示:

页面代码

View Code
<div class="divContent">
<table width="70%">
<tr>
<td align="right">
选择职位:
</td>
<td align="left">
<asp:DropDownList ID="ddlJobName" runat="server" AutoPostBack="False" >
</asp:DropDownList>
</td>
<td>
<asp:Button ID="btnAddParent" runat="server" Text="添加父节点"
CssClass="inputbuttonnormal" onclick="btnAddParent_Click"
/>
</td>
<td class="style1">
<asp:Button ID="btnAddChild" runat="server" Text="添加叶子节点"
CssClass="inputbuttonnormal" onclick="btnAddChild_Click"
/>
</td>
<td>
<asp:Button ID="btnSave" runat="server" Text="保存" CssClass="inputbuttonnormal"
onclick="btnSave_Click" />
</td>
<td>
<asp:Button ID="btnDeleted" runat="server" Text="删除节点" CssClass="inputbuttonnormal"
onclick="btnDeleted_Click" />
</td>
</tr>
<tr>
<td align="left">
<asp:TreeView ID="TvJobFilter" runat="server" ImageSet="Arrows"
ShowLines="True">
<SelectedNodeStyle BorderColor="#000066" />
</asp:TreeView>
</td>
</tr>
</table>
</div>

因为treeview  控件的节点包含信息较少,所以我们扩展了

 [Serializable]
    public class CustomerTreeNode 
    {
        public int Id { get; set; }
        public string Code { get; set; }
        public string ParentJobId { get; set; }
        public string ParentJobName { get; set; }
        public string JobId { get; set; }
        public string JobName { get; set; }
        public string Path { get; set; }
    }

  生成code,也就是path 的基础数据

 private static char[] constant =  
          {  
            '0','1','2','3','4','5','6','7','8','9',  
            'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',  
            'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'  
          };
        private static char[] constantNumber =  
          {  
            '0','1','2','3','4','5','6','7','8','9'  
          };

        public static string GenerateRandomNumber(int Length)
        {
            System.Text.StringBuilder newRandom = new System.Text.StringBuilder(62);
            Random rd = new Random();
            for (int i = 0; i < Length; i++)
            {
                newRandom.Append(constant[rd.Next(62)]);
            }
            return newRandom.ToString();
        }

在开始的时候添加一个空的根节点,然后我们就可以通过添加“叶子节点”,“父节点”,“修改节点”,“”删除节点“功能来实现要的功能

添加父节点:

 选中要添加的节点,我们要做的是插入一条新的记录,更新选中节点及其子节点的path,从选中节点的code 替换成诚如节点的code+”|“+选中节点的code。

删除节点:

删除选中的节点,把选中节点的子的路径替换,从选中节点的path替换成path去掉删除节点的code

具体的代码如下

 

下载

posted @ 2012-02-29 11:54  留云  阅读(370)  评论(0编辑  收藏  举报