我有一个从数据库中检索一组记录的方法。
我将此数据映射到业务对象 - 让我们调用业务对象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;
}
}
}
}
}
}
}
}
答案 0 :(得分:1)
This related post可能有帮助......
更新:此处的代码支持以下评论...您需要进行编辑以支持自己的课程。
public class Proc
{
public System.Diagnostics.Process RealProc;
public List<Proc> SubProcs = null;
}
void Main()
{
var Processes = from p in System.Diagnostics.Process.GetProcesses() select new Proc { RealProc = p, SubProcs = null };
while (Processes.Any(pr => pr.SubProcs == null))
{
foreach(Proc pr in Processes)
{
pr.RealProc.Id.Dump();
pr.SubProcs = Processes.Where(prx => prx.RealProc.ParentId == pr.Id).ToList(); // doesn't work because no ParentId
}
}
}
答案 1 :(得分:1)
我想这个答案有点晚了,但现在就去了。
尝试使用.LookUp(...)
扩展方法和递归lambda表达式:
var lookup = e.Results.ToLookup(x => x.ParentId);
Action<IEnumerable<Process>> addChildren = null;
addChildren = ps =>
{
foreach (var p in ps)
{
p.ProcessChildren = lookup[p.EntityId].ToList();
addChildren(p.ProcessChildren);
}
};
var rootProcesses = e.Results.Where(x => x.ParentId == 0);
addChildren(rootProcesses);
这对我创建的测试数据很好。我没有使用ContainerLevel
属性,因为ParentId
关系隐式定义了级别。