我最近遇到了一个奇怪的问题。我在db中有一个名为Task的表。任务可以具有父任务和多个子任务(自联接)。我编写了一个存储过程,它使用CTE(公用表表达式)将项目中的所有任务返回给他们的子项和子项达到n级。我的要求结果如下
结果成功实现。您可以在第一列中看到缩进以显示层次关系。问题是我是以“糟糕的方式”做到的。下面是我的观点代码
<table cellspacing="0">
<%foreach (var it in Model.list.Where(x=>x.ParentID == null))
{
int x = 1;%>
<tr>
<td width="150"><div class="wrapper" style="width:18px;"> </div><%:it.TOC %></td>
<td><%:it.label %></td>
<td><%:it.StartDate%></td>
<td><%:it.EndDate%></td>
<td><%:it.smallDescription %></td>
</tr>
<%=Model.CallRecursion(it,Model.list,ref x) %>
<%} %>
你可以看到Call recursion方法已经在递归返回html字符串的模型上定义。下面是CallRecursion方法的代码。
public string CallRecursion(TempModel item, List<TempModel> all,ref int count)
{
if(all.Where(x=>x.ParentID == item.ID).Count() == 0)
return "";
else
{
count++;
string retval = "<tr>";
foreach (var kids in all.Where(x => x.ParentID == item.ID))
{
retval += "<td><div style='width:"+count*18+"px;' class='wrapper'> </div><span>" + kids.TOC + "</span></td><td>" + kids.label + "</td><td>" + kids.StartDate + "</td><td>" + kids.EndDate+"</td><td>"+kids.smallDescription+"</td></tr>"+
CallRecursion(kids, all,ref count);
}
count--;
return retval;
}
}
我的问题是如何以更清洁的方式实现这一目标。我不知道我是否可以递归地调用部分视图来呈现html,如果是的话,动态是什么。意见和建议表示赞赏。
答案 0 :(得分:1)
为什么不修改CTE以给出结果,如下所示指定每行树中的哪个级别。通过这种方式,SQL已经在进行递归调用,所以为什么要在应用程序代码中重做它。
通过这种方式,您的方法可以简化为仅将TreeLevel
乘以像素数量,以提供正确的缩进。不需要递归。只需循环遍历结果模型。
在任何情况下,我认为你对每个项目TreeLevel都有更多的价值,因为你可以做其他的事情,比如'给我一个所有根节点的概述',导致Number
等于1,2的行和3
TreeLevel Number Other_data
0 1 ...
1 1.1 ...
1 1.2 ...
2 1.2.1 ...
2 1.2.1 ...
0 2 ...
1 2.1 ...
1 2.2 ...
2 2.1.2 ...
3 2.1.2.1 ...
0 3 ...
关于CTE,请查看4guysfromrolla中的article,其中显示了如何将层次结构(TreeLevel)值包含在CTE结果集中。
有关原始代码的其他说明 - 在从代码构造HTML时使用TagBuilder类。国际海事组织,这将更清洁,更好。没有神奇的弦乐构建..