我有一种方法从数据库中检索一组记录。Linq构建分层列表
我将这些数据映射到一个业务对象 - 让我们称之为业务对象ProcessModel。 ProcessModel中的一个属性是一个名为ProcessChildren的列表。该属性是List。
因此,数据通过各种字段/属性进行链接。在层次结构列表顶部有一个对象,然后该对象在其ProcessChildren属性中具有多个对象,这些对象在其ProcessChildren属性中具有多个对象等。
无论如何,我写了相当多的代码来遍历返回数据集,然后构建分层列表,然后将其绑定到Silverlight中的TreeView。
我会非常感激,如果有人可以提供一个更清洁,更简单的方法来做到这一点,无论是使用LINQ,或使用LINQ或其他方法通过扩展方法。
我已经包含了我目前正在使用的代码,希望能够更好地说明我想实现的目标。
var processes = new List<Process>();
var rootLevelProcesses = new List<Process>();
var allProcesses = new List<Process>();
foreach (Process process in e.Results)
{
process.ProcessChildren = new List<Process>();
if (process.ParentId > 0 || (process.ParentId == 0 && process.EntityId == 1))
{
allProcesses.Add(process);
}
}
var rootProcess =
(from parent in e.Results
where parent.EntityType == 1 && parent.ContainerLevel <= 1
select parent).FirstOrDefault();
processes.Add(rootProcess);
var level2Processes = (from parent in allProcesses
where parent.EntityType == 1 && parent.ContainerLevel == 2
select parent).ToList();
foreach (Process process in level2Processes)
{
var level3Processes = (from parent in allProcesses
where parent.EntityType == 1 && parent.ContainerLevel == 3
select parent).ToList();
process.ProcessChildren = level3Processes;
}
processes[0].ProcessChildren = level2Processes;
foreach (Process process in processes)
{
if (process.ProcessChildren != null && process.ProcessChildren.Count > 0)
{
foreach (Process level1 in process.ProcessChildren)
{
if (level1.EntityType == 1)
{
var children =
(from child in allProcesses
where child.ParentId == level1.EntityId
select child).ToList();
level1.ProcessChildren = children;
foreach (Process level2 in level1.ProcessChildren)
{
if (level2.EntityType == 1)
{
children =
(from child in allProcesses
where child.ParentId == level2.EntityId
select child).ToList();
level2.ProcessChildren = children;
foreach (Process level3 in level2.ProcessChildren)
{
if (level3.EntityType == 1)
{
children =
(from child in allProcesses
where child.ParentId == level3.EntityId
select child).ToList();
level3.ProcessChildren = children;
}
}
}
}
}
}
}
}
谢谢 - 但我不确定这是否能解决我的问题。之所以这么说,是因为那个人似乎在做我以前看过的很多东西 - 哪里有顶级,哪些是子级别的东西。就我而言,它是动态的,基于列表中的每个项目。一个项目可能有一个孩子,那么这个孩子可能有三个孩子,那么其中一个孩子可能有一个孩子等等... – Chris 2010-01-07 19:03:20
好吧,我会认为你可以把一些东西放在循环中...像(伪代码):while procs.Any(p => p.SubProcs == null){foreach其中proc.SubProcs = null {proc.SubProcs = <解析原始列表以填充subprocs>列表}} - 这将递归地查找所有.. 。注意,assigment应该为叶子进程返回一个空的列表,以避免无限循环。 – 2010-01-07 19:09:15
顺便说一句,我没有在Process上看到'ParentId'属性...那里是什么?如果我能弄明白,那么我可以发布实际的工作代码 – 2010-01-07 19:18:25