重构此代码

时间:2010-10-05 02:55:42

标签: c# linq treeview lambda

我正在尝试根据各个部门(lstStaff)的工作人员列表填充树状视图。

public class Staff
{
    public int StaffID { get; set; }
    public string StaffName { get; set; }
    public int DeptID { get; set; }
    public string DepartmentName { get; set; }
}

结果应该是这样的:

A部门

  • 约翰
  • 戴夫

B部门

  • 安迪
  • 莱昂

我写了以下代码。但是,我认为代码应该进一步重构。

RadTreeNode deptNode;
RadTreeNode staffNode;
var departments = (from d in lstStaff
                   where !string.IsNullOrEmpty(d.DepartmentName) 
                select new { d.DeptId, d.DepartmentName })
                .Distinct();

foreach (var d in departments)
{
    //add department node
    deptNode = new RadTreeNode()
    {
        Value = d.DeptId,
        Text = d.DepartmentName
    };
    tvwDepartmentCases.Nodes.Add(deptNode);

    //add staff nodes to department node
    var staffs = lstStaff
                    .ToList()
                    .Where(x => x.DeptId == d.DeptId);

    foreach (var s in staffs)
    {
        staffNode = new RadTreeNode()
        {
            Value = s.StaffID,
            Text = s.StaffName
        };
        deptNode.Nodes.Add(staffNode);
    }
}

欢迎任何评论。谢谢!

6 个答案:

答案 0 :(得分:2)

使用GroupBy运算符,它很简单,看起来更好。

var departmentGroups = lstStaff.GroupBy(staff => 
    new { staff.DeptID, staff.DepartmentName });

foreach (var department in departmentGroups)
{
    var deptNode = new RadTreeNode()
    {
        Value = department.Key.DeptID,
        Text = department.Key.DepartmentName
    };

    tvwDepartmentCases.Nodes.Add(deptNode);

    foreach (var staffMember in department)
    {
        var staffNode = new RadTreeNode()
        {
            Value = staffMember.StaffID,
            Text = staffMember.StaffName
        };
        deptNode.Nodes.Add(staffNode);
    }
}

它的复杂性也较低,因为您不需要为每个部门遍历整个lstStaff集合。

答案 1 :(得分:1)

var grping = from staff in lstStaff
             where !String.IsNullOrEmpty(staff.StaffName)
             group staff.StaffName by staff.DepartmentName;

foreach (var deptGrp in grping)
{
         //add a high level node using deptGrp.Key
         foreach (var staffName in deptGrp) 
               //add a lower level node
}

答案 2 :(得分:0)

我认为你拥有的东西非常简单易读。它有提升性能的空间(可能可以忽略不计)但你会牺牲一些可读性。话虽如此,你不喜欢你想要进一步重构的当前解决方案吗?

答案 3 :(得分:0)

我现在必须跑去工作,但我认为你在循环中做了太多的查询。您应该使用.ToLookup在循环之前为工作人员组创建查找表,并使用查找表来查找每个部门的工作人员。

答案 4 :(得分:0)

我会写 -

foreach(var member in lstStaff)
 var deptNode = FindDeptNode(member.DeptId, member.DeptName);
 deptNode.Add(member.StaffId, member.StaffName);


.. // in FindDeptNode

if(!departmentsTreeView.ContainssNode(deptId, deptName))
 departmentsTreeView.Add(deptId, deptName);

return departmentsTreeView[deptId, deptName];

您可以将其转换为可编辑的形式。

干杯。

答案 5 :(得分:0)

我更进一步,从查询中创建人员节点。这在逻辑上比较清晰,因为我们拥有在该点创建节点所需的所有信息。遗憾的是,无法以干净,可读的方式在查询中创建部门节点。

var depts = from staff in lstStaff
            where !string.IsNullOrEmpty(staff.DepartmentName)
            group   //staff nodes
                new RadTreeNode  //each item in the group is a node
                {
                    Value = staff.StaffID,
                    Text = staff.StaffName,
                }
            by      //departments
                new
                {
                    staff.DeptID,
                    staff.DepartmentName,
                };
foreach (var dept in depts)
{
    var deptNode = new RadTreeNode
    {
        Value = dept.Key.DeptID,
        Text = dept.Key.DepartmentName,
    };
    deptNode.Nodes.AddRange(dept.ToArray());
    tvwDepartmentCases.Nodes.Add(deptNode);
}