Utilizzando Linq to Sql mi sono reso conto di quanto sia facile ed immediato scrivere codice che intergra all'interno della sintassi di Linq delle chiamate a metodi.
Una delle attività che affronto spesso, è scrivere metodi ricorsivi per manipolare le gerarchie. Con Linq è tutto molto più facile eseguire questa attività da codice, possiamo infatti creare una funzione ricorsiva inserendo all'interno di Linq la chiamata alla funzione che stiamo scrivendo.
Nell'esempio che vi propongo esplodiamo l'organigramma definito nella tabella Employes del database AdventureWorks.
Vediamo subito il codice.
[code language="C#"]
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
/// <summary>
/// Costruttore del form
/// </summary>
public Form1()
{
InitializeComponent();
// Chiamata al metodo per generare la struttura ad albero.
this.treeView1.Nodes.AddRange(this.GetNodes(0));
}
/// <summary>
/// Metodo per generare la struttura ad albero con Linq
/// </summary>
/// <param name="managerid"> Id del manager. 0 se si vuole ottenere ottenere l'albero a partire dal General Manager</param>
/// <returns></returns>
private TreeNode[] GetNodes(int managerid)
{
// DataContext definito con Linq
DbDataContext db = new DbDataContext();
var result = from empl in db.Employees // Tabella Employees
join cont in db.Contacts on // Join con la tabella Contacts per ricavare il nome degli impiegati
empl.ContactID equals cont.ContactID
where (managerid == 0 && empl.ManagerID == null) || // Verifico se devo cercare il General Manager
empl.ManagerID == managerid // Where per ottenere i rami figli del manager passato
let node = new TreeNode(empl.EmployeeID.ToString() + " " + cont.LastName, // Utilizzo Let per generare una
// variabile all'interno della query che contiene
// direttamente il TreeNode da inseride nella TreeView
GetNodes(empl.EmployeeID)) // Il TreeNode accetta un array di childs.
// Inseriamo una chiamata al metodo che stiamo scrivendo per rendere la
// funzione ricorsiva.
select node; // Limitiamo la select all'elenco di nodi del ramo corrente.
return result.ToArray(); // Trasformiamo il tutto in un array di TreeNodes
}
}
}
[/code]
Ecco il risultato

Allego il progetto VS2008. Per farlo funzionare vi serve il DB AdventureWorks che potete scaricare dal sito Microsoft.