├── .gitignore ├── .idea ├── .idea.HierarchySample │ └── .idea │ │ ├── .gitignore │ │ ├── encodings.xml │ │ ├── indexLayout.xml │ │ └── vcs.xml └── .idea.PostgreSqlLTreeSample │ └── .idea │ └── workspace.xml ├── HierarchySample.sln ├── PostgreSql ├── FamilyTreeContext.cs ├── Halfling.cs ├── Interest.cs ├── InterestsContext.cs ├── PostgreSql.csproj ├── Program.cs ├── Seeder.cs └── UserSecrets.cs └── SqlServer ├── FamilyTreeContext.cs ├── Halfling.cs ├── Program.cs ├── Seeder.cs └── SqlServer.csproj /.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | obj/ 3 | /packages/ 4 | riderModule.iml 5 | /_ReSharper.Caches/ -------------------------------------------------------------------------------- /.idea/.idea.HierarchySample/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Rider ignored files 5 | /.idea.PostgreSqlLTreeSample.iml 6 | /modules.xml 7 | /projectSettingsUpdater.xml 8 | /contentModel.xml 9 | # Editor-based HTTP Client requests 10 | /httpRequests/ 11 | # Datasource local storage ignored files 12 | /dataSources/ 13 | /dataSources.local.xml 14 | -------------------------------------------------------------------------------- /.idea/.idea.HierarchySample/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/.idea.HierarchySample/.idea/indexLayout.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/.idea.HierarchySample/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/.idea.PostgreSqlLTreeSample/.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | PostgreSqlLTreeSample/PostgreSqlLTreeSample.csproj 5 | SqlServer/SqlServer.csproj 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 21 | 22 | 23 | 24 | 25 | 27 | 28 | 29 | 30 | 31 | 34 | { 35 | "keyToString": { 36 | "RunOnceActivity.OpenProjectViewOnStart": "true", 37 | "RunOnceActivity.ShowReadmeOnStart": "true", 38 | "WebServerToolWindowFactoryState": "false", 39 | "vue.rearranger.settings.migration": "true" 40 | }, 41 | "keyToStringList": { 42 | "rider.external.source.directories": [ 43 | "C:\\Users\\ajcvi\\AppData\\Roaming\\JetBrains\\Rider2022.3\\resharper-host\\DecompilerCache", 44 | "C:\\Users\\ajcvi\\AppData\\Roaming\\JetBrains\\Rider2022.3\\resharper-host\\SourcesCache", 45 | "C:\\Users\\ajcvi\\AppData\\Local\\Symbols\\src" 46 | ] 47 | } 48 | } 49 | 50 | 51 | 68 | 69 | 86 | 87 | 88 | 89 | 90 | 91 | 1679010542255 92 | 98 | 99 | 100 | 101 | 103 | 104 | 105 | 106 | 108 | -------------------------------------------------------------------------------- /HierarchySample.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PostgreSql", "PostgreSql\PostgreSql.csproj", "{E9AADCBF-B164-4FED-BB1B-7A3430922F15}" 4 | EndProject 5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SqlServer", "SqlServer\SqlServer.csproj", "{D3510C03-D8E2-41AA-B4EA-32DFEC272051}" 6 | EndProject 7 | Global 8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 9 | Debug|Any CPU = Debug|Any CPU 10 | Release|Any CPU = Release|Any CPU 11 | EndGlobalSection 12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 13 | {E9AADCBF-B164-4FED-BB1B-7A3430922F15}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 14 | {E9AADCBF-B164-4FED-BB1B-7A3430922F15}.Debug|Any CPU.Build.0 = Debug|Any CPU 15 | {E9AADCBF-B164-4FED-BB1B-7A3430922F15}.Release|Any CPU.ActiveCfg = Release|Any CPU 16 | {E9AADCBF-B164-4FED-BB1B-7A3430922F15}.Release|Any CPU.Build.0 = Release|Any CPU 17 | {D3510C03-D8E2-41AA-B4EA-32DFEC272051}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 18 | {D3510C03-D8E2-41AA-B4EA-32DFEC272051}.Debug|Any CPU.Build.0 = Debug|Any CPU 19 | {D3510C03-D8E2-41AA-B4EA-32DFEC272051}.Release|Any CPU.ActiveCfg = Release|Any CPU 20 | {D3510C03-D8E2-41AA-B4EA-32DFEC272051}.Release|Any CPU.Build.0 = Release|Any CPU 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /PostgreSql/FamilyTreeContext.cs: -------------------------------------------------------------------------------- 1 | public class FamilyTreeContext : DbContext 2 | { 3 | public DbSet Halflings => Set(); 4 | 5 | protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 6 | => optionsBuilder 7 | .UseNpgsql( 8 | $"Server=127.0.0.1;Database=Halflings;User Id=postgres;Password={UserSecrets.Read("Halflings:Password")};") 9 | .EnableSensitiveDataLogging() 10 | .LogTo(Console.WriteLine, LogLevel.Information); 11 | } -------------------------------------------------------------------------------- /PostgreSql/Halfling.cs: -------------------------------------------------------------------------------- 1 | public class Halfling 2 | { 3 | public Halfling(LTree pathFromPatriarch, string name, int? yearOfBirth = null) 4 | { 5 | PathFromPatriarch = pathFromPatriarch; 6 | Name = name; 7 | YearOfBirth = yearOfBirth; 8 | } 9 | 10 | public int Id { get; private set; } 11 | public LTree PathFromPatriarch { get; set; } 12 | public string Name { get; set; } 13 | public int? YearOfBirth { get; set; } 14 | } -------------------------------------------------------------------------------- /PostgreSql/Interest.cs: -------------------------------------------------------------------------------- 1 | public class Interest 2 | { 3 | private Interest() 4 | { 5 | } 6 | 7 | public Interest(string path) 8 | { 9 | Id = new LTree(path); 10 | } 11 | 12 | public LTree Id { get; private set; } 13 | public string? Comments { get; set; } 14 | } -------------------------------------------------------------------------------- /PostgreSql/InterestsContext.cs: -------------------------------------------------------------------------------- 1 | public class InterestsContext : DbContext 2 | { 3 | public DbSet Interests => Set(); 4 | 5 | protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 6 | => optionsBuilder 7 | .UseNpgsql( 8 | $"Server=127.0.0.1;Database=Interests;User Id=postgres;Password={UserSecrets.Read("Interests:Password")};") 9 | .EnableSensitiveDataLogging() 10 | .LogTo(Console.WriteLine, LogLevel.Information); 11 | } -------------------------------------------------------------------------------- /PostgreSql/PostgreSql.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net7.0 6 | enable 7 | enable 8 | Preview 9 | 10 | 4833167f-1fb7-4c6a-ae1c-7e84b54aa02b 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /PostgreSql/Program.cs: -------------------------------------------------------------------------------- 1 | await using var context = new FamilyTreeContext(); 2 | 3 | await context.Database.EnsureDeletedAsync(); 4 | await context.Database.EnsureCreatedAsync(); 5 | await context.Seed(); 6 | context.ChangeTracker.Clear(); 7 | Console.WriteLine(); 8 | 9 | // // Find a generations 10 | // var level = 2; 11 | // var halflingGeneration = await context.Halflings 12 | // .Where(h => h.PathFromPatriarch.NLevel == level) 13 | // .ToListAsync(); 14 | // 15 | // Console.WriteLine(); 16 | // Console.WriteLine($"Generation {level}: {string.Join(", ", halflingGeneration.Select(e => e.Name))}"); 17 | 18 | // // Find all generations 19 | // var halflingGenerations = await context.Halflings 20 | // .GroupBy(h => h.PathFromPatriarch.NLevel) 21 | // .ToListAsync(); 22 | // 23 | // Console.WriteLine(); 24 | // foreach (var group in halflingGenerations) 25 | // { 26 | // Console.WriteLine($"Generation {group.Key}: {string.Join(", ", group.Select(e => e.Name))}"); 27 | // } 28 | 29 | // // Find all descendents 30 | // var name = "Mungo"; 31 | // var descendents = await context.Halflings.Where( 32 | // h1 => h1.PathFromPatriarch.IsDescendantOf( 33 | // context.Halflings.Single(h2 => h2.Name == name && h1.Id != h2.Id).PathFromPatriarch)) 34 | // .ToListAsync(); 35 | // 36 | // Console.WriteLine(); 37 | // Console.WriteLine($"All descendents of {name}: {string.Join(", ", descendents.Select(e => e.Name))}"); 38 | 39 | // // Find all ancestors 40 | // var name = "Longo"; 41 | // var ancestors = await context.Halflings.Where( 42 | // h1 => h1.PathFromPatriarch.IsAncestorOf( 43 | // context.Halflings.Single(h2 => h2.Name == name && h1.Id != h2.Id).PathFromPatriarch)) 44 | // .ToListAsync(); 45 | // 46 | // Console.WriteLine(); 47 | // Console.WriteLine($"All ancestors of {name}: {string.Join(", ", ancestors.Select(e => e.Name))}"); 48 | 49 | // // Find direct descendents 50 | // var name = "Mungo"; 51 | // var directDescendents = await context.Halflings.Where( 52 | // h1 => h1.PathFromPatriarch.IsDescendantOf( 53 | // context.Halflings.Single( 54 | // h2 => h2.Name == name 55 | // && h1.PathFromPatriarch.NLevel == h2.PathFromPatriarch.NLevel + 1) 56 | // .PathFromPatriarch)) 57 | // .ToListAsync(); 58 | // 59 | // Console.WriteLine(); 60 | // Console.WriteLine($"Direct descendents of {name}: {string.Join(", ", directDescendents.Select(e => e.Name))}"); 61 | 62 | // // Find direct ancestor 63 | // var name = "Bilbo"; 64 | // var directAncestor = await context.Halflings.SingleOrDefaultAsync( 65 | // h1 => h1.PathFromPatriarch.IsAncestorOf( 66 | // context.Halflings.Single( 67 | // h2 => h2.Name == name 68 | // && h1.PathFromPatriarch.NLevel == h2.PathFromPatriarch.NLevel - 1).PathFromPatriarch)); 69 | // 70 | // Console.WriteLine(); 71 | // Console.WriteLine($"The direct ancestor of {name} is {directAncestor?.Name}"); 72 | 73 | // // Find direct ancestor 2 74 | // var name = "Bilbo"; 75 | // var directAncestor = await context.Halflings 76 | // .SingleOrDefaultAsync( 77 | // h1 => h1.PathFromPatriarch == context.Halflings 78 | // .Single(h2 => h2.Name == name).PathFromPatriarch.Subpath(0, -1)); 79 | // 80 | // Console.WriteLine(); 81 | // Console.WriteLine($"The direct ancestor of {name} is {directAncestor?.Name}"); 82 | 83 | // // Find direct descendents 2 84 | // var name = "Mungo"; 85 | // var directDescendents = await context.Halflings 86 | // .Where(h1 => h1.PathFromPatriarch.NLevel > 0 && h1.PathFromPatriarch.Subpath(0, -1) == context.Halflings 87 | // .Single(h2 => h2.Name == name).PathFromPatriarch) 88 | // .ToListAsync(); 89 | // 90 | // Console.WriteLine(); 91 | // Console.WriteLine($"Direct descendents of {name}: {string.Join(", ", directDescendents.Select(e => e.Name))}"); 92 | 93 | // // Find closest common ancestor 94 | // var halfling1 = await context.Halflings.SingleAsync(halfling => halfling.Name == "Angelica"); 95 | // var halfling2 = await context.Halflings.SingleAsync(halfling => halfling.Name == "Prisca"); 96 | // 97 | // var commonAncestor = await context.Halflings 98 | // .Where(e => e.PathFromPatriarch == 99 | // context.Halflings.Where(e => e.Name == halfling1.Name) 100 | // .SelectMany(h1 => context.Halflings.Where(e => e.Name == halfling2.Name), 101 | // (h1, h2) => LTree.LongestCommonAncestor(h1.PathFromPatriarch, h2.PathFromPatriarch)) 102 | // .SingleOrDefault()) 103 | // .SingleOrDefaultAsync(); 104 | // 105 | // Console.WriteLine(); 106 | // Console.WriteLine($"The common ancestor of {halfling1.Name} and {halfling2.Name} is {commonAncestor?.Name}"); 107 | 108 | // // Pattern matching 109 | // var pattern = "*.!pictures@.Astronomy.*"; 110 | // var interests = await context.Interests 111 | // .Where(e => e.Id.MatchesLQuery(pattern)) 112 | // .ToListAsync(); 113 | // 114 | // Console.WriteLine(); 115 | // Console.WriteLine($"Matches for '{pattern}':"); 116 | // Console.WriteLine(" " + string.Join(Environment.NewLine + " ", interests.Select(e => e.Id))); 117 | 118 | // // Full text search 119 | // var text = "Astro*% & !pictures@"; // "Astro* & !pictures@"; 120 | // var interests = await context.Interests 121 | // .Where(e => e.Id.MatchesLTxtQuery(text)) 122 | // .ToListAsync(); 123 | // 124 | // Console.WriteLine(); 125 | // Console.WriteLine($"Matches for '{text}':"); 126 | // Console.WriteLine(" " + string.Join(Environment.NewLine + " ", interests.Select(e => e.Id))); 127 | -------------------------------------------------------------------------------- /PostgreSql/Seeder.cs: -------------------------------------------------------------------------------- 1 | public static class Seeder 2 | { 3 | public static async Task Seed(this FamilyTreeContext context) 4 | { 5 | await context.AddRangeAsync( 6 | new Halfling(new LTree(""), "Balbo", 1167), 7 | new Halfling(new LTree("1"), "Mungo", 1207), 8 | new Halfling(new LTree("2"), "Pansy", 1212), 9 | new Halfling(new LTree("3"), "Ponto", 1216), 10 | new Halfling(new LTree("4"), "Largo", 1220), 11 | new Halfling(new LTree("5"), "Lily", 1222), 12 | new Halfling(new LTree("1.1"), "Bungo", 1246), 13 | new Halfling(new LTree("1.2"), "Belba", 1256), 14 | new Halfling(new LTree("1.3"), "Longo", 1260), 15 | new Halfling(new LTree("1.4"), "Linda", 1262), 16 | new Halfling(new LTree("1.5"), "Bingo", 1264), 17 | new Halfling(new LTree("3.1"), "Rosa", 1256), 18 | new Halfling(new LTree("3.2"), "Polo"), 19 | new Halfling(new LTree("4.1"), "Fosco", 1264), 20 | new Halfling(new LTree("1.1.1"), "Bilbo", 1290), 21 | new Halfling(new LTree("1.3.1"), "Otho", 1310), 22 | new Halfling(new LTree("1.5.1"), "Falco", 1303), 23 | new Halfling(new LTree("3.2.1"), "Posco", 1302), 24 | new Halfling(new LTree("3.2.2"), "Prisca", 1306), 25 | new Halfling(new LTree("4.1.1"), "Dora", 1302), 26 | new Halfling(new LTree("4.1.2"), "Drogo", 1308), 27 | new Halfling(new LTree("4.1.3"), "Dudo", 1311), 28 | new Halfling(new LTree("1.3.1.1"), "Lotho", 1310), 29 | new Halfling(new LTree("1.5.1.1"), "Poppy", 1344), 30 | new Halfling(new LTree("3.2.1.1"), "Ponto", 1346), 31 | new Halfling(new LTree("3.2.1.2"), "Porto", 1348), 32 | new Halfling(new LTree("3.2.1.3"), "Peony", 1350), 33 | new Halfling(new LTree("4.1.2.1"), "Frodo", 1368), 34 | new Halfling(new LTree("4.1.3.1"), "Daisy", 1350), 35 | new Halfling(new LTree("3.2.1.1.1"), "Angelica", 1381)); 36 | 37 | await context.SaveChangesAsync(); 38 | } 39 | 40 | public static async Task Seed(this InterestsContext context) 41 | { 42 | await context.AddRangeAsync( 43 | new Interest("Top"), 44 | new Interest("Top.Science"), 45 | new Interest("Top.Science.Astronomy"), 46 | new Interest("Top.Science.Astronomy.Astrophysics"), 47 | new Interest("Top.Science.Astronomy.Cosmology"), 48 | new Interest("Top.Hobbies"), 49 | new Interest("Top.Hobbies.Amateurs_Astronomy"), 50 | new Interest("Top.Collections"), 51 | new Interest("Top.Collections.Pictures"), 52 | new Interest("Top.Collections.Pictures.Astronomy"), 53 | new Interest("Top.Collections.Pictures.Astronomy.Stars"), 54 | new Interest("Top.Collections.Pictures.Astronomy.Galaxies"), 55 | new Interest("Top.Collections.Pictures.Astronomy.Astronauts")); 56 | 57 | await context.SaveChangesAsync(); 58 | } 59 | } -------------------------------------------------------------------------------- /PostgreSql/UserSecrets.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json; 2 | using Microsoft.Extensions.Configuration.UserSecrets; 3 | 4 | public class UserSecrets 5 | { 6 | public static string Read(string key) 7 | => JsonSerializer.Deserialize>( 8 | File.ReadAllText(PathHelper.GetSecretsPathFromSecretsId( 9 | typeof(UserSecrets).Assembly.GetCustomAttribute()!.UserSecretsId)))![key]; 10 | } -------------------------------------------------------------------------------- /SqlServer/FamilyTreeContext.cs: -------------------------------------------------------------------------------- 1 | public class FamilyTreeContext : DbContext 2 | { 3 | public DbSet Halflings => Set(); 4 | 5 | protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 6 | => optionsBuilder 7 | .UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=Halflings", b => b.UseHierarchyId()) 8 | .EnableSensitiveDataLogging() 9 | .LogTo(Console.WriteLine, LogLevel.Information); 10 | } -------------------------------------------------------------------------------- /SqlServer/Halfling.cs: -------------------------------------------------------------------------------- 1 | public class Halfling 2 | { 3 | public Halfling(HierarchyId pathFromPatriarch, string name, int? yearOfBirth = null) 4 | { 5 | PathFromPatriarch = pathFromPatriarch; 6 | Name = name; 7 | YearOfBirth = yearOfBirth; 8 | } 9 | 10 | public int Id { get; private set; } 11 | public HierarchyId PathFromPatriarch { get; set; } 12 | public string Name { get; set; } 13 | public int? YearOfBirth { get; set; } 14 | } -------------------------------------------------------------------------------- /SqlServer/Program.cs: -------------------------------------------------------------------------------- 1 | await using var context = new FamilyTreeContext(); 2 | 3 | await context.Database.EnsureDeletedAsync(); 4 | await context.Database.EnsureCreatedAsync(); 5 | await context.Seed(); 6 | context.ChangeTracker.Clear(); 7 | Console.WriteLine(); 8 | 9 | // // Find a generation 10 | // var level = 2; 11 | // var halflingGeneration = await context.Halflings 12 | // .Where(h => h.PathFromPatriarch.GetLevel() == level) 13 | // .ToListAsync(); 14 | // 15 | // Console.WriteLine(); 16 | // Console.WriteLine($"Generation {level}: {string.Join(", ", halflingGeneration.Select(e => e.Name))}"); 17 | 18 | // // Find all generations 19 | // var halflingGenerations = await context.Halflings 20 | // .GroupBy(h => h.PathFromPatriarch.GetLevel()) 21 | // .ToListAsync(); 22 | // 23 | // Console.WriteLine(); 24 | // foreach (var group in halflingGenerations) 25 | // { 26 | // Console.WriteLine($"Generation {group.Key}: {string.Join(", ", group.Select(e => e.Name))}"); 27 | // } 28 | 29 | // // Find all descendents 30 | // var name = "Mungo"; 31 | // var descendents = await context.Halflings.Where( 32 | // h1 => h1.PathFromPatriarch.IsDescendantOf( 33 | // context.Halflings.Single(h2 => h2.Name == name && h1.Id != h2.Id).PathFromPatriarch)) 34 | // .ToListAsync(); 35 | // 36 | // Console.WriteLine(); 37 | // Console.WriteLine($"All descendents of {name}: {string.Join(", ", descendents.Select(e => e.Name))}"); 38 | 39 | // // Find all ancestors 40 | // var name = "Longo"; 41 | // var ancestors = await context.Halflings.Where( 42 | // h1 => context.Halflings.Single(h2 => h2.Name == name && h1.Id != h2.Id).PathFromPatriarch 43 | // .IsDescendantOf(h1.PathFromPatriarch)) 44 | // .ToListAsync(); 45 | // 46 | // Console.WriteLine(); 47 | // Console.WriteLine($"All ancestors of {name}: {string.Join(", ", ancestors.Select(e => e.Name))}"); 48 | 49 | // // Find direct descendents 50 | // var name = "Mungo"; 51 | // var directDescendents = await context.Halflings 52 | // .Where(h1 => h1.PathFromPatriarch.GetAncestor(1) == context.Halflings 53 | // .Single(h2 => h2.Name == name).PathFromPatriarch) 54 | // .ToListAsync(); 55 | // 56 | // Console.WriteLine(); 57 | // Console.WriteLine($"Direct descendents of {name}: {string.Join(", ", directDescendents.Select(e => e.Name))}"); 58 | 59 | // // Find direct ancestor 60 | // var name = "Bilbo"; 61 | // var directAncestor = await context.Halflings 62 | // .SingleOrDefaultAsync( 63 | // h1 => h1.PathFromPatriarch == context.Halflings 64 | // .Single(h2 => h2.Name == name).PathFromPatriarch.GetAncestor(1)); 65 | // 66 | // Console.WriteLine(); 67 | // Console.WriteLine($"The direct ancestor of {name} is {directAncestor?.Name}"); 68 | 69 | // Find closest common ancestor 70 | var halfling1 = await context.Halflings.SingleAsync(halfling => halfling.Name == "Frodo"); 71 | var halfling2 = await context.Halflings.SingleAsync(halfling => halfling.Name == "Bilbo"); 72 | 73 | var commonAncestor = await context.Halflings 74 | .Where(h => halfling1.PathFromPatriarch.IsDescendantOf(h.PathFromPatriarch) 75 | && halfling2.PathFromPatriarch.IsDescendantOf(h.PathFromPatriarch)) 76 | .OrderByDescending(h => h.PathFromPatriarch.GetLevel()) 77 | .FirstOrDefaultAsync(); 78 | 79 | Console.WriteLine(); 80 | Console.WriteLine($"The common ancestor of {halfling1.Name} and {halfling2.Name} is {commonAncestor?.Name}"); 81 | -------------------------------------------------------------------------------- /SqlServer/Seeder.cs: -------------------------------------------------------------------------------- 1 | public static class Seeder 2 | { 3 | public static async Task Seed(this FamilyTreeContext context) 4 | { 5 | await context.AddRangeAsync( 6 | new Halfling(HierarchyId.Parse("/"), "Balbo", 1167), 7 | new Halfling(HierarchyId.Parse("/1/"), "Mungo", 1207), 8 | new Halfling(HierarchyId.Parse("/2/"), "Pansy", 1212), 9 | new Halfling(HierarchyId.Parse("/3/"), "Ponto", 1216), 10 | new Halfling(HierarchyId.Parse("/4/"), "Largo", 1220), 11 | new Halfling(HierarchyId.Parse("/5/"), "Lily", 1222), 12 | new Halfling(HierarchyId.Parse("/1/1/"), "Bungo", 1246), 13 | new Halfling(HierarchyId.Parse("/1/2/"), "Belba", 1256), 14 | new Halfling(HierarchyId.Parse("/1/3/"), "Longo", 1260), 15 | new Halfling(HierarchyId.Parse("/1/4/"), "Linda", 1262), 16 | new Halfling(HierarchyId.Parse("/1/5/"), "Bingo", 1264), 17 | new Halfling(HierarchyId.Parse("/3/1/"), "Rosa", 1256), 18 | new Halfling(HierarchyId.Parse("/3/2/"), "Polo"), 19 | new Halfling(HierarchyId.Parse("/4/1/"), "Fosco", 1264), 20 | new Halfling(HierarchyId.Parse("/1/1/1/"), "Bilbo", 1290), 21 | new Halfling(HierarchyId.Parse("/1/3/1/"), "Otho", 1310), 22 | new Halfling(HierarchyId.Parse("/1/5/1/"), "Falco", 1303), 23 | new Halfling(HierarchyId.Parse("/3/2/1/"), "Posco", 1302), 24 | new Halfling(HierarchyId.Parse("/3/2/2/"), "Prisca", 1306), 25 | new Halfling(HierarchyId.Parse("/4/1/1/"), "Dora", 1302), 26 | new Halfling(HierarchyId.Parse("/4/1/2/"), "Drogo", 1308), 27 | new Halfling(HierarchyId.Parse("/4/1/3/"), "Dudo", 1311), 28 | new Halfling(HierarchyId.Parse("/1/3/1/1/"), "Lotho", 1310), 29 | new Halfling(HierarchyId.Parse("/1/5/1/1/"), "Poppy", 1344), 30 | new Halfling(HierarchyId.Parse("/3/2/1/1/"), "Ponto", 1346), 31 | new Halfling(HierarchyId.Parse("/3/2/1/2/"), "Porto", 1348), 32 | new Halfling(HierarchyId.Parse("/3/2/1/3/"), "Peony", 1350), 33 | new Halfling(HierarchyId.Parse("/4/1/2/1/"), "Frodo", 1368), 34 | new Halfling(HierarchyId.Parse("/4/1/3/1/"), "Daisy", 1350), 35 | new Halfling(HierarchyId.Parse("/3/2/1/1/1/"), "Angelica", 1381)); 36 | 37 | await context.SaveChangesAsync(); 38 | } 39 | } -------------------------------------------------------------------------------- /SqlServer/SqlServer.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net7.0 6 | enable 7 | enable 8 | Preview 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | --------------------------------------------------------------------------------