我们从数据库里读取的数据都是无层次结构的二维数据,通过O/RM工具一般都可以直接转换到集合类型,之前一直使用递推将无层次的集合类型转换为有层次的集合类型。现在不用递归实现了无限层次结构。具体代码和分析如下:
定义对象,这里使用经常用到的部门对象
1
public
class
Department
2 {
3 /// <summary>
4 /// 唯一标识
5 /// </summary>
6 public int Id { get ; set ; }
7
8 /// <summary>
9 /// 部门名称
10 /// </summary>
11 public string Name { get ; set ; }
12
13 /// <summary>
14 /// 上级部门唯一标识
15 /// </summary>
16 public int ParentId { get ; set ; }
17
18 /// <summary>
19 /// 所有直接下一级部门
20 /// </summary>
21 public IList < Department > ChildDepartments;
22 }
2 {
3 /// <summary>
4 /// 唯一标识
5 /// </summary>
6 public int Id { get ; set ; }
7
8 /// <summary>
9 /// 部门名称
10 /// </summary>
11 public string Name { get ; set ; }
12
13 /// <summary>
14 /// 上级部门唯一标识
15 /// </summary>
16 public int ParentId { get ; set ; }
17
18 /// <summary>
19 /// 所有直接下一级部门
20 /// </summary>
21 public IList < Department > ChildDepartments;
22 }
准备测试用的数据集合,这里使用List
1
///
<summary>
2 /// 取得测试数据
3 /// </summary>
4 /// <returns></returns>
5 public static IList < Department > GetDepartments()
6 {
7
8 var l = new List < Department > ()
9 {
10 // ParentId = 0 表示顶层节点
11 new Department() {Id = 2 , Name = " 董事会 " ,ParentId = 1 },
12 new Department() {Id = 4 , Name = " 行政部 " ,ParentId = 1 },
13 new Department() {Id = 5 , Name = " 研发部 " ,ParentId = 1 },
14 new Department() {Id = 1 , Name = " 浙江**股份有限公司 " ,ParentId = 0 },
15 new Department() {Id = 6 , Name = " 营销中心 " ,ParentId = 1 },
16 new Department() {Id = 7 , Name = " 人力资源部 " ,ParentId = 4 },
17 new Department() {Id = 8 , Name = " 采购部 " ,ParentId = 4 },
18 new Department() {Id = 3 , Name = " 总经理办公室 " ,ParentId = 1 },
19 new Department() {Id = 9 , Name = " .net技术研发部 " ,ParentId = 5 },
20 new Department() {Id = 10 , Name = " 销售一部 " ,ParentId = 6 },
21 new Department() {Id = 11 , Name = " java技术研发部 " ,ParentId = 5 },
22 new Department() {Id = 12 , Name = " 销售二部 " ,ParentId = 6 },
23 new Department() {Id = 13 , Name = " 第一项目组 " ,ParentId = 9 },
24 new Department() {Id = 14 , Name = " 华东市场部 " ,ParentId = 12 },
25 new Department() {Id = 15 , Name = " 华南市场部 " ,ParentId = 12 },
26 new Department() {Id = 16 , Name = " 第二项目组 " ,ParentId = 9 },
27 new Department() {Id = 17 , Name = " 上海**集团 " ,ParentId = 0 }
28
29 };
30
31
32 return l;
33 }
2 /// 取得测试数据
3 /// </summary>
4 /// <returns></returns>
5 public static IList < Department > GetDepartments()
6 {
7
8 var l = new List < Department > ()
9 {
10 // ParentId = 0 表示顶层节点
11 new Department() {Id = 2 , Name = " 董事会 " ,ParentId = 1 },
12 new Department() {Id = 4 , Name = " 行政部 " ,ParentId = 1 },
13 new Department() {Id = 5 , Name = " 研发部 " ,ParentId = 1 },
14 new Department() {Id = 1 , Name = " 浙江**股份有限公司 " ,ParentId = 0 },
15 new Department() {Id = 6 , Name = " 营销中心 " ,ParentId = 1 },
16 new Department() {Id = 7 , Name = " 人力资源部 " ,ParentId = 4 },
17 new Department() {Id = 8 , Name = " 采购部 " ,ParentId = 4 },
18 new Department() {Id = 3 , Name = " 总经理办公室 " ,ParentId = 1 },
19 new Department() {Id = 9 , Name = " .net技术研发部 " ,ParentId = 5 },
20 new Department() {Id = 10 , Name = " 销售一部 " ,ParentId = 6 },
21 new Department() {Id = 11 , Name = " java技术研发部 " ,ParentId = 5 },
22 new Department() {Id = 12 , Name = " 销售二部 " ,ParentId = 6 },
23 new Department() {Id = 13 , Name = " 第一项目组 " ,ParentId = 9 },
24 new Department() {Id = 14 , Name = " 华东市场部 " ,ParentId = 12 },
25 new Department() {Id = 15 , Name = " 华南市场部 " ,ParentId = 12 },
26 new Department() {Id = 16 , Name = " 第二项目组 " ,ParentId = 9 },
27 new Department() {Id = 17 , Name = " 上海**集团 " ,ParentId = 0 }
28
29 };
30
31
32 return l;
33 }
上面的List集合是没有层次结构的,实际项目中一般来源于数据库的二维表。
下面将List转换成具有层次结构的List
1
public
static
IList
<
Department
>
ToTree(IList
<
Department
>
ds)
2 {
3 // 定义字典类型,将List转换成字典类型,集合中的元素个数是相同的
4 var dic = new Dictionary < int , Department > (ds.Count);
5
6 foreach (var department in ds)
7 {
8 dic.Add(department.Id,department);
9 }
10
11 // 通过一次遍历集合,转换成具有层次结构的类型
12 foreach (var department in dic.Values)
13 {
14 if (dic.ContainsKey(department.ParentId))
15 {
16 if (dic[department.ParentId].ChildDepartments == null )
17 dic[department.ParentId].ChildDepartments = new List < Department > ();
18
19 dic[department.ParentId].ChildDepartments.Add(department);
20 }
21 }
22
23 // 仅仅选择最顶层节点返回
24 return dic.Values.Where(t => t.ParentId == 0 ).ToList();
25 }
2 {
3 // 定义字典类型,将List转换成字典类型,集合中的元素个数是相同的
4 var dic = new Dictionary < int , Department > (ds.Count);
5
6 foreach (var department in ds)
7 {
8 dic.Add(department.Id,department);
9 }
10
11 // 通过一次遍历集合,转换成具有层次结构的类型
12 foreach (var department in dic.Values)
13 {
14 if (dic.ContainsKey(department.ParentId))
15 {
16 if (dic[department.ParentId].ChildDepartments == null )
17 dic[department.ParentId].ChildDepartments = new List < Department > ();
18
19 dic[department.ParentId].ChildDepartments.Add(department);
20 }
21 }
22
23 // 仅仅选择最顶层节点返回
24 return dic.Values.Where(t => t.ParentId == 0 ).ToList();
25 }
以下是测试代码
1
var t
=
Util.ToTree(Util.GetDepartments());
通过调试可以清楚看到当前的List已经具有层次结构了,该集合中只有两个顶层节点的元素了。
以下是打包后代码