记录转化为有层次结构的树状列表的通用算法

问题说明:

在获取数据库记录数据的时候, 通常返回的ArrayList集合, 没有了层次关系. 如果每次根据PID重新到数据库获取记录, 可以做到, 但有以下几个缺点:

1. 访问数据库记录次数随着记录的增多而增多

2. 由于需要多次访问数据库, 因此访问速度受影响

3. 需要数据库访问层的支持, 并对记录进行转化, 耦合性太强

4. 通用性不好, 每次需要一个新的类型列表, 就需要重新编写

解决方法:

我根据原有的树状结构算法代码, 编写一个通用的算法, 利用反射原理, 递归的对数据进行筛选.

这样只需要访问数据库一次, 然后就在内存中遍历, 而且适合于所有具有(PID, ID, Name)属性的实体类集合的排序.

 

如我需要生成设备类型实体类集合的树状结构时候, 代码如下:

ArrayList equipTypelist = equipmentType.GetAll();
    equipTypelist = CollectionHelper.GetTreeItems(equipTypelist);
    this.ddlEquipmentTypes.DataSource = equipTypelist;
    this.ddlEquipmentTypes.DataTextField = "Name";
    this.ddlEquipmentTypes.DataValueField = "ID";
    this.ddlEquipmentTypes.DataBind();

    this.ddlEquipmentType.Items.Insert(0, new ListItem("(全部)", "0"));

    public class CollectionHelper
    {            
        private static ArrayList Fill(int pID, int level, ArrayList list)
        {
            ArrayList returnList = new ArrayList();
            foreach(object obj in list)
            {
                int typePID = (int)ReflectionUtil.GetProperty(obj, "PID");
                int typeID = (int)ReflectionUtil.GetProperty(obj, "ID");
                string typeName = ReflectionUtil.GetProperty(obj, "Name") as string;

                if(pID == typePID)
                {
                    string newName = new string('-', level * 4) + typeName;
                    ReflectionUtil.SetProperty(obj, "Name", newName);
                    returnList.Add(obj);

                    returnList.AddRange(Fill(typeID, level+1, list));
                }
            }
            return returnList;
        }

        /// <summary>
        /// 生成有层次结构的列表
        /// </summary>
        /// <param name="list">具有Name,ID,PID成员的任何集合</param>
        /// <returns></returns>
        public static ArrayList GetTreeItems(ArrayList list)
        {
            return Fill(-1, 0, list);
        }    
    }

    public sealed class ReflectionUtil
    {
        private ReflectionUtil()
        { }

        public static BindingFlags bf = BindingFlags.DeclaredOnly | BindingFlags.Public |
            BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static;

        public static void SetProperty(object obj, string name, object value)
        {
            PropertyInfo fi = obj.GetType().GetProperty(name, bf);
            fi.SetValue(obj, value,null);
        }

        public static object GetProperty(object obj, string name)
        {
            PropertyInfo fi = obj.GetType().GetProperty(name, bf);
            return fi.GetValue(obj,null);
        }
}

效果图如下

本文转自博客园伍华聪的博客,原文链接:记录转化为有层次结构的树状列表的通用算法,如需转载请自行联系原博主。

时间: 2025-01-05 06:10:45

记录转化为有层次结构的树状列表的通用算法的相关文章

C#发现之旅-高性能ASP.NET树状列表控件(上)

已有树状列表控件分析发现问题 近期发现有人在ASP.NET项目开发中使用一种叫dtree的树状列表组件加载缓慢.这也是笔者撰写本章的动机.毛主席教导我们,做事要发现问题,分析问题和解决问题.首先我们发现了已有的树状列表WEB控件加载缓慢的问题,接下来就很自然的是分析问题了. 下图就是dtree 运行界面的例子 分析问题 现在我们分析问题,对使用dtree生成树状列表的程序代码的分析,可以了解程序运行过程如下图所示 在这样的程序中,首先服务器端的C#代码查询数据库,然后根据查询所得数据拼凑出一个J

C#发现之旅-高性能ASP.NET树状列表控件(下)

TreeNode 模板 TreeNode模板是XSLT模板文档的主要部分,其代码为 <!-- ******************* 输出一个树状列表节点 *************************** --> <xsl:template name="TreeNode"> <!-- 定义一个 Level 参数,表示节点层次,默认 0 --> <xsl:param name="Level">0</xsl:p

C#发现之旅-高性能ASP.NET树状列表控件(中)

第一段HTML代码块 若控件的"DynamicLoadChildNodes"属性值为true,也就是控件运行在客户端动态加载子节点,则输出支持客户端动态加载子节点的HTML代码,首先输出一个名为"SkyTreeViewControlTempXML"的XML数据岛标签,并将它的 "onreadystatechange"事件绑定到"SkyTreeViewControlDynamicLoadChildNodes"的 Javascri

JS无限树状列表实现代码_javascript技巧

tree.js 复制代码 代码如下: /******************************** 树形组织框架列表 v1.0 2011年1月6日 作者:flycrosscloud ********************************/ //初始化框架 var allImages = { HasNodeClose: "<img src='image/ftv2pnode.gif'/>", //包含子节点,闭合状态(不是最后一个) HasNodeOpen: &

destoon分类树状列表

在使用destoon的过程中要制作一些小工具,会用到模块下的分类,如果使用系统自己带的,需要引入一大批js,对于小工具来说就有点臃肿了 那么如何调用来他的分类列表出来呢,制作了一个小函数 具体代码与使用方法见下方 <? define('IN_DESTOON', true); require 'common.inc.php'; function InitClassSelectOption($ParentID,$ChkID,$db) { $sql="SELECT * from dt_categ

php无限分类, 支持输出树状图

<?php /** * 通用的树型类,可以生成任何树型结构 */ class tree { /** * 生成树型结构所需要的2维数组 * @var array */ var $arr = array(); /** * 生成树型结构所需修饰符号,可以换成图片 * @var array */ var $icon = array('│','├','└'); /** * @access private */ var $ret = ''; /** * 构造函数,初始化类 * @param array 2维

C# 系统应用之TreeView控件 (一).显示树状磁盘文件目录及加载图标

在C#系统应用毕设U盘防御软件中需要实现文件不可恢复的删除,首先需要实现类似于资源管理器的界面,通过TreeView控件显示"我的电脑"所有磁盘文件树状目录并加载相应图标.显示结果如下图所示: 一. 界面设计 主窗体是一个Windowss窗体文件,工程命名为SecureTree.分别从工具箱中左边拖一个TreeView控件,名称(Name)为directoryTree;右侧文件列表ListView控件,名称为filesList.然后从工具箱中拖两个ImageList控件,分别命名为di

BootStrap树状图显示功能_jquery

这是我根据bootstrap的折叠设计的树状图显示,只有二级显示,可以用在简单的目录等 右端可以再次修改,显示为滑动块 - 引用部分 <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>@ViewBag.Title - 腾实信绩效管理系统</title&

SQL Story(十一)--树状表游戏

树状结构的存储与管理,是每一个在关系型数据库平台上工作的程序员早晚都要遇到的问题.说大不大,怎么都能解决,说小不小,处理不好,有的是麻烦等着你.仁者见仁,智者见智,公说公有理,婆说婆有理(谁用机箱砸我?机箱是个好东西,乱丢会摔坏硬盘的,你看我话没说完你又把显示器丢了--),咳咳,好吧,闲话少说,我们从最大路的处理风格谈一谈吧.这里面的大部分内容并非我的独创,从很久很久以前,数据库程序员们就这样做啦. 树状表的结构化表达     在一切开始前,我们先就树状表的表示方式达成一个共识.在关系型数据库中