-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Implemented hierarchy IDs * Added readme
- Loading branch information
1 parent
143cb4b
commit 5c3fbf8
Showing
7 changed files
with
126 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
using Common; | ||
using Microsoft.EntityFrameworkCore; | ||
|
||
namespace HierarchyIds; | ||
|
||
public class ApplicationDbContext : DbContext | ||
{ | ||
public DbSet<Employee> Employees => Set<Employee>(); | ||
|
||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) | ||
{ | ||
optionsBuilder | ||
.UseSqlServer(DbConnectionFactory.Create("HierarchyIds"), builder => builder.UseHierarchyId()); | ||
} | ||
|
||
protected override void OnModelCreating(ModelBuilder modelBuilder) | ||
{ | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
using Microsoft.EntityFrameworkCore; | ||
|
||
namespace HierarchyIds; | ||
|
||
public class Employee | ||
{ | ||
public int Id { get; private set; } | ||
public required HierarchyId Path { get; init; } | ||
public required string Name { get; init; } | ||
|
||
public override string ToString() | ||
{ | ||
return $"Id: {Id}, Name: {Name}, Path: {Path}"; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer.HierarchyId" Version="8.0.0" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
using HierarchyIds; | ||
using Microsoft.EntityFrameworkCore; | ||
|
||
Console.WriteLine("Hierarchy IDs Sample"); | ||
|
||
using var db = new ApplicationDbContext(); | ||
db.Database.EnsureDeleted(); | ||
db.Database.EnsureCreated(); | ||
|
||
var employees = new List<Employee> | ||
{ | ||
new() { Name = "CEO", Path = HierarchyId.Parse("/")}, | ||
new() { Name = "Product Manager", Path = HierarchyId.Parse("/1/")}, | ||
new() { Name = "Tech Lead", Path = HierarchyId.Parse("/1/1/")}, | ||
new() { Name = "Senior Dev", Path = HierarchyId.Parse("/1/1/1/")}, | ||
new() { Name = "Junior Dev", Path = HierarchyId.Parse("/1/1/2/")}, | ||
new() { Name = "Intern", Path = HierarchyId.Parse("/1/1/3/")}, | ||
}; | ||
|
||
db.Employees.AddRange(employees); | ||
db.SaveChanges(); | ||
|
||
var techLead = db.Employees.First(e => e.Path == HierarchyId.Parse("/1/1/")); | ||
|
||
// Get tech lead subordinates | ||
var techLeadSubordinates = db.Employees | ||
.AsNoTracking() | ||
.Where(e => e.Path.IsDescendantOf(techLead.Path)) | ||
.ToList(); | ||
|
||
Console.WriteLine("Tech Lead Team"); | ||
techLeadSubordinates.ForEach(Console.WriteLine); | ||
|
||
// Get tech lead parents | ||
var techLeadManagers = FindAllAncestors("Tech Lead").ToList(); | ||
Console.WriteLine("Tech Lead Managers"); | ||
techLeadManagers.ForEach(Console.WriteLine); | ||
|
||
var ceo = db.Employees.First(e => e.Path == HierarchyId.Parse("/")); | ||
|
||
Console.WriteLine($"Is Tech Lead a descendant of CEO? {techLead.Path.IsDescendantOf(ceo.Path)}"); | ||
Console.WriteLine($"Is CEO a descendant of Tech Lead? {ceo.Path.IsDescendantOf(techLead.Path)}"); | ||
|
||
Console.ReadLine(); | ||
|
||
IQueryable<Employee> FindAllAncestors(string name) | ||
=> db.Employees.Where( | ||
ancestor => db.Employees | ||
.Single( | ||
descendent => | ||
descendent.Name == name | ||
&& ancestor.Id != descendent.Id) | ||
.Path.IsDescendantOf(ancestor.Path)) | ||
.OrderByDescending(ancestor => ancestor.Path.GetLevel()); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# Hierarchy IDs | ||
|
||
Hierarchy IDs are a special data type in SQL Server that allow you to store and query hierarchical data. This is a great way to store data that has a parent-child relationship, such as a file system, organizational chart, or product categories. | ||
|
||
The DB is then able to run queries such as finding all descendants of a node, or finding the common ancestor of two nodes. | ||
|
||
NOTE: You will need the CLR enabled on your SQL Server instance for this to work. The Azure SQL Edge Docker image does not support this. | ||
|
||
|
||
## Use Cases | ||
|
||
- Store and query hierarchical (i.e. tree-like) data | ||
|
||
## Resources | ||
|
||
- [EF Core Docs | Hierarchy IDs](https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-8.0/whatsnew#hierarchyid-in-net-and-ef-core) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters