En utilisant linq2sql, vous pourriez faire :
List<PageInfo> GetHierarchicalPages()
{
var pages = myContext.PageInfos.ToList();
var parentPages = pages.Where(p=>p.ParentId == null).ToList();
foreach(var page in parentPages)
{
BuildTree(
page,
p=> p.Pages = pages.Where(child=>p.pageId == child.ParentId).ToList()
);
}
}
void BuildTree<T>(T parent, Func<T,List<T>> setAndGetChildrenFunc)
{
foreach(var child in setAndGetChildrenFunc(parent))
{
BuildTree(child, setAndGetChildrenFunc);
}
}
En supposant que vous définissiez une propriété Pages dans PageInfo comme :
public partial class PageInfo{
public List<PageInfo> Pages{get;set;}
}
Le traitement pour l'obtenir sur une hiérarchie se produit du côté de l'application Web, ce qui évite une charge supplémentaire sur le serveur sql. Notez également que ce type d'informations est un candidat idéal pour la mise en cache.
Vous pouvez faire le rendu comme Rex l'a mentionné. Vous pouvez également développer un peu cette implémentation et lui faire prendre en charge les interfaces de hiérarchie et utiliser les contrôles asp.net.
Mise à jour 1 : Pour la variation de rendu que vous avez demandée sur un commentaire, vous pouvez :
var sb = new System.IO.StringWriter();
var writer = new HtmlTextWriter(sb);
// rex's rendering code
var html = sb.ToString();