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

本文介绍了一种使用反射和递归实现的通用算法,该算法能够将数据库查询得到的扁平列表转换为具有层次结构的数据集合,适用于任何拥有PID、ID和Name属性的实体类集合。
问题说明:
在获取数据库记录数据的时候, 通常返回的ArrayList集合, 没有了层次关系. 如果每次根据PID重新到数据库获取记录, 可以做到, 但有以下几个缺点:
1. 访问数据库记录次数随着记录的增多而增多
2. 由于需要多次访问数据库, 因此访问速度受影响
3. 需要数据库访问层的支持, 并对记录进行转化, 耦合性太强
4. 通用性不好, 每次需要一个新的类型列表, 就需要重新编写
解决方法:
我根据原有的树状结构算法代码, 编写一个通用的算法, 利用反射原理, 递归的对数据进行筛选.
这样只需要访问数据库一次, 然后就在内存中遍历, 而且适合于所有具有(PID, ID, Name)属性的实体类集合的排序.
 
如我需要生成设备类型实体类集合的树状结构时候, 代码如下:
None.gifArrayList equipTypelist = equipmentType.GetAll();
None.gif    equipTypelist 
= CollectionHelper.GetTreeItems(equipTypelist);
None.gif    
this.ddlEquipmentTypes.DataSource = equipTypelist;
None.gif    
this.ddlEquipmentTypes.DataTextField = "Name";
None.gif    
this.ddlEquipmentTypes.DataValueField = "ID";
None.gif    
this.ddlEquipmentTypes.DataBind();
None.gif
None.gif    
this.ddlEquipmentType.Items.Insert(0new ListItem("(全部)""0"));

None.gif    public class CollectionHelper
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif{            
InBlock.gif        
private static ArrayList Fill(int pID, int level, ArrayList list)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            ArrayList returnList 
= new ArrayList();
InBlock.gif            
foreach(object obj in list)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
int typePID = (int)ReflectionUtil.GetProperty(obj, "PID");
InBlock.gif                
int typeID = (int)ReflectionUtil.GetProperty(obj, "ID");
InBlock.gif                
string typeName = ReflectionUtil.GetProperty(obj, "Name"as string;
InBlock.gif
InBlock.gif                
if(pID == typePID)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    
string newName = new string('-', level * 4+ typeName;
InBlock.gif                    ReflectionUtil.SetProperty(obj, 
"Name", newName);
InBlock.gif                    returnList.Add(obj);
InBlock.gif
InBlock.gif                    returnList.AddRange(Fill(typeID, level
+1, list));
ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

InBlock.gif            
return returnList;
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 生成有层次结构的列表
InBlock.gif        
/// </summary>
InBlock.gif        
/// <param name="list">具有Name,ID,PID成员的任何集合</param>
ExpandedSubBlockEnd.gif        
/// <returns></returns>

InBlock.gif        public static ArrayList GetTreeItems(ArrayList list)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return Fill(-10, list);
ExpandedSubBlockEnd.gif        }
    
ExpandedBlockEnd.gif    }

None.gif

None.gif    public sealed class ReflectionUtil
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif{
InBlock.gif        
private ReflectionUtil()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{ }
InBlock.gif
InBlock.gif        
public static BindingFlags bf = BindingFlags.DeclaredOnly | BindingFlags.Public |
InBlock.gif            BindingFlags.NonPublic 
| BindingFlags.Instance | BindingFlags.Static;
InBlock.gif
InBlock.gif        
public static void SetProperty(object obj, string name, object value)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            PropertyInfo fi 
= obj.GetType().GetProperty(name, bf);
InBlock.gif            fi.SetValue(obj, value,
null);
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public static object GetProperty(object obj, string name)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            PropertyInfo fi 
= obj.GetType().GetProperty(name, bf);
InBlock.gif            
return fi.GetValue(obj,null);
ExpandedSubBlockEnd.gif        }

ExpandedBlockEnd.gif}

效果图如下
树状列表效果图.jpg
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值