E' vero che la ricorsione non è mai necessaria, ma questo mi sembra proprio un caso tipicamente ricorsivo.
Nell'esempio di sotto ho utilizzato una tabella che, in origine mi serviva per creare un menu.
La stessa tabella mi serve in questo caso per crearmi la struttura di Directory-files su disco.
le voci principali della tabella sono
id_menu, tuo id_cat
text, tuo nome_cat
id_parent, tuo parent_id
type, D per directory, F per file
codice:
Option Strict On
Partial Class prove_a
Inherits System.Web.UI.Page
Protected Sub Button1_Click(sender As Object, e As System.EventArgs) Handles Button1.Click
CreaMenu()
End Sub
Private Sub CreaMenu()
'estraggo tutte le voci, file e directory
Dim dt As DataTable = ora.GetDataTable(gl.StringaConnessione, String.Format("select * from menu where id_modulo = {0} ", 2))
'considero solo i file e le directory di primo livello
Dim rows As DataRow() = dt.Select("id_parent is null")
For Each row As DataRow In rows
Dim id_menu As Integer = CInt(row("id_menu"))
Dim text As String = l.NullToString(row("text")).Replace("\"c, "_"c).Replace("/"c, "_"c).Replace("|"c, "_"c).Replace("<"c, "_"c).Replace(">"c, "_"c).Replace(":"c, "_"c)
Dim type As String = l.NullToString(row("type"))
'creo tutta la struttura in c:\tmp per non sporcarmi il computer
text = String.Format("c:\tmp\{0}", text)
'se directory
If String.Equals(type, "D", StringComparison.OrdinalIgnoreCase) Then
Directory.CreateDirectory(text)
PopolaMenu(dt, id_menu, text)
Else
'se file
File.CreateText(text)
End If
Next
End Sub
Protected Sub PopolaMenu(dt As DataTable, id_parent As Integer, textParent As String)
Dim rows As DataRow() = dt.Select(String.Format("id_parent = {0}", id_parent))
For Each row As DataRow In rows
Dim id_menu As Integer = CInt(row("id_menu"))
Dim text As String = l.NullToString(row("text")).Replace("\"c, "_"c).Replace("/"c, "_"c).Replace("|"c, "_"c).Replace("<"c, "_"c).Replace(">"c, "_"c).Replace(":"c, "_"c)
Dim type As String = l.NullToString(row("type"))
text = String.Format("{0}\{1}", textParent, text)
If String.Equals(type, "D", StringComparison.OrdinalIgnoreCase) Then
Directory.CreateDirectory(text)
'richiamo ricorsivamente PopolaMenu
PopolaMenu(dt, id_menu, text)
Else
File.CreateText(text)
End If
Next
End Sub
End Class