├── .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 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
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 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 | 1679010542255
92 |
93 |
94 | 1679010542255
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
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 |
--------------------------------------------------------------------------------