Tra le tante novità della versione 8 di EF, una di quelle più comode è il supporto nativo per il tipo [bHierarchiId] di Sql Server. Per chi non ha dimestichezza con questo tipo, basta pensare che è una colonna di una tabella che rappresenta la posizione di quel record all'interno di una gerarchia. Se prendiamo come esempio un'organigramma di uffici, la colonna di tipo HierarchiId rappresenta la posizione dell'ufficio all'interno dell'organigramma. Il formato è genericamente rappresentato con la lista degli Id dei record padre separata dal carattere "/". Immaginiamo di avere un ufficio che come valore nella colonna ha /3/4. Questo significa che questo ufficio ha come id 4, il quale a sua volta ha un padre con id 3 il quale a sua volta ha come padre l'ufficio principale. Questa organizzazione dei dati rende estremamente semplice la scrittura di query che navigano tra alberi senza dover fare query ricorsive complesse.
EF supporta il tipo HierarchiId attraverso il package Microsoft.EntityFrameworkCore.SqlServer.Abstractions quindi dobbiamo sempre aggiungerlo ai nostri progetti che devono lavorare con questo tipo di dati. Una volta aggiunto il package, dobbiamo configurare il DbContext con il seguente codice.
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(connectionString, opt => opt.UseHierarchyId());
}Finita la configurazione possiamo passare al primo passo per l'utilizzo dello HierarchId cioè la scrittura di record. Il package che abbiamo aggiunto all'inizio importa un tipo speciale: Microsoft.EntityFrameworkCore.HierarchyId. Le proprietà che mappano verso una colonna di tipo HierarchiId devono essere di questo tipo. Questo ha un metodo statico Parse che prende in input una stringa che rappresenta una gerarchia chee poi EF converte nell'equivalente di SQL Server. Nel prossimo esempio vediamo come creare entity e persisterne la gerarchia sul database.
public class Halfling
{
public Halfling(HierarchyId pathFromPatriarch, string name)
{
PathFromPatriarch = pathFromPatriarch;
Name = name;
}
public int Id { get; private set; }
public HierarchyId PathFromPatriarch { get; set; }
public string Name { get; set; }
}
using var ctx = new EFContext();
ctx.AddRange(
new Halfling(HierarchyId.Parse("/"), "Balbo", 1167),
new Halfling(HierarchyId.Parse("/1/"), "Mungo", 1207),
new Halfling(HierarchyId.Parse("/2/"), "Pansy", 1212),
new Halfling(HierarchyId.Parse("/3/"), "Ponto", 1216),
new Halfling(HierarchyId.Parse("/4/"), "Largo", 1220),
new Halfling(HierarchyId.Parse("/5/"), "Lily", 1222),
new Halfling(HierarchyId.Parse("/1/1/"), "Bungo", 1246),
new Halfling(HierarchyId.Parse("/1/2/"), "Belba", 1256),
new Halfling(HierarchyId.Parse("/1/3/"), "Longo", 1260),
new Halfling(HierarchyId.Parse("/1/4/"), "Linda", 1262),
new Halfling(HierarchyId.Parse("/1/5/"), "Bingo", 1264),
new Halfling(HierarchyId.Parse("/3/1/"), "Rosa", 1256),
new Halfling(HierarchyId.Parse("/3/2/"), "Polo"),
new Halfling(HierarchyId.Parse("/4/1/"), "Fosco", 1264),
new Halfling(HierarchyId.Parse("/1/1/1/"), "Bilbo", 1290),
new Halfling(HierarchyId.Parse("/1/3/1/"), "Otho", 1310),
new Halfling(HierarchyId.Parse("/1/5/1/"), "Falco", 1303),
new Halfling(HierarchyId.Parse("/3/2/1/"), "Posco", 1302),
new Halfling(HierarchyId.Parse("/3/2/2/"), "Prisca", 1306),
new Halfling(HierarchyId.Parse("/4/1/1/"), "Dora", 1302),
new Halfling(HierarchyId.Parse("/4/1/2/"), "Drogo", 1308),
new Halfling(HierarchyId.Parse("/4/1/3/"), "Dudo", 1311),
new Halfling(HierarchyId.Parse("/1/3/1/1/"), "Lotho", 1310),
new Halfling(HierarchyId.Parse("/1/5/1/1/"), "Poppy", 1344),
new Halfling(HierarchyId.Parse("/3/2/1/1/"), "Ponto", 1346),
new Halfling(HierarchyId.Parse("/3/2/1/2/"), "Porto", 1348),
new Halfling(HierarchyId.Parse("/3/2/1/3/"), "Peony", 1350),
new Halfling(HierarchyId.Parse("/4/1/2/1/"), "Frodo", 1368),
new Halfling(HierarchyId.Parse("/4/1/3/1/"), "Daisy", 1350),
new Halfling(HierarchyId.Parse("/3/2/1/1/1/"), "Angelica", 1381)
);
await ctx.SaveChangesAsync();Questo esempio crea una gerarchia di persone. Balbo è il capostipite che ha 5 figli di cui alcuni, a loro volta, hanno altri figli. Come possiamo vedere, il codice è estremamente semplice e non necessita di molte spiegazioni. Nei prossimi script vedremo come eseguire query su gerarchie di oggetti.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Utilizzo di CSS Scroll Snap per realizzare un carousel
Costruire endpoint SSE in ASP.NET Core
Middleware e telemetria alle chiamate AI con Microsoft.Extensions.AI
Il nuovo persistent state in Blazor
Agentic Workflows in GitHub
.NET Aspire vs Dapr: differenze, sovrapposizioni e integrazione
Introduzione ai GitHub Agentic Workflows
Modificare lo stile in una QuickGrid Blazor
Nuova modale riconnessione Blazor
Response streaming con Blazor e .NET 10
Bloccare il traffico di rete in uscita dal runner di GitHub
Integrare Agenti A2A in Azure API Management
I più letti di oggi
- Effettuare il multi-checkout in linea nelle pipeline di Azure DevOps
- Utilizzare un DataContext specifico per la modalità design time di Blend e Visual Studio nei controlli Silverlight
- Le DirectInk API nella Universal Windows Platform
- Accedere a risorse e immagini in Windows Store app di Windows 8
- Gli oggetti CallOut di Expression Blend 4.0
- Esaminare documenti XML con namespace utilizzando LINQ to XML
- Alleggerire le applicazioni WPF sfruttando gli oggetti Freezable


