Custom Dynamic DataSources - Data Relationships
Requirements
Data can have relationships to other data, allowith code to navigate from one to the other.
Tree Referencing Children
The TreeBasic
DataSource creates a list of entities which point to the children.
This is a simple example how to establish relationships between generated data.
In this example, every entity has a SubItems
property, which contains the IDs of the related children.
IDs are a common way to declare relationships, but there are other options as well.
Example Reading some Data
- Root name: Root Node
- Root ID: 1
- Item count in field
SubItems
: 2 - Title of first child: Sub Item 101
-
Looping through children of Root
- Sub Item 101
- Sub Item 102
Show Tree of Data
-
Item:
Root Node (id: 1)
-
Sub-Items on field SubItems - found 2
-
Item:
Sub Item 101 (id: 101)
-
Sub-Items on field SubItems - found 2
- Item: Sub Item 1011 (id: 1011)
- Item: Sub Item 1012 (id: 1012)
-
Sub-Items on field SubItems - found 2
- Item: Sub Item 102 (id: 102)
-
Item:
Sub Item 101 (id: 101)
-
Sub-Items on field SubItems - found 2
Flat List of Items 5
- Root Node (#1)
- Sub Item 101 (#101)
- Sub Item 102 (#102)
- Sub Item 1011 (#1011)
- Sub Item 1012 (#1012)
Tree with Children and Parents
The previous example only allowed navigating down from parent to children. To allow the children to know the parent, we can also provide that relationship.
Show Tree of Data
-
Item:
Root Node (id: 1)
-
Sub-Items on field SubItems - found 2
-
Item:
Sub Item 101 (id: 101)
Parent (field Parent): Root Node (id: 1)-
Sub-Items on field SubItems - found 2
-
Item:
Sub Item 1011 (id: 1011)
Parent (field Parent): Sub Item 101 (id: 101) -
Item:
Sub Item 1012 (id: 1012)
Parent (field Parent): Sub Item 101 (id: 101)
-
Item:
Sub Item 1011 (id: 1011)
-
Sub-Items on field SubItems - found 2
-
Item:
Sub Item 102 (id: 102)
Parent (field Parent): Root Node (id: 1)
-
Item:
Sub Item 101 (id: 101)
-
Sub-Items on field SubItems - found 2
Flat List of Items 5
- Root Node (#1)
- Sub Item 101 (#101)
- Sub Item 102 (#102)
- Sub Item 1011 (#1011)
- Sub Item 1012 (#1012)
Relationships without ID #1
The previous example used the Id
number of items to establish a relationship.
But there are many cases, where no ID-number exists.
For example, data coming from a WebService or files might just have a string identifier.
The following example establishes the relationship based on a Path
string:
- Each item has a
Path
which is a reliably identifier - To tell the relationship manager that we have more keys, we must add a
RelationshipKeys
property - The
RelationshipKeys
can have many keys for advanced reasons, so it's anarray
- In this example, we just add the
Path
to the list of keys - In this example, the parent supplies a list of paths which it expects to have as children
Show Tree of Data
-
Item:
Root Node (id: 1)
-
Sub-Items on field SubItems - found 2
-
Item:
Sub Item 101 (id: 2)
-
Sub-Items on field SubItems - found 2
- Item: Sub Item 1011 (id: 4)
- Item: Sub Item 1012 (id: 5)
-
Sub-Items on field SubItems - found 2
- Item: Sub Item 102 (id: 3)
-
Item:
Sub Item 101 (id: 2)
-
Sub-Items on field SubItems - found 2
Flat List of Items 5
- Root Node (#1)
- Sub Item 101 (#2)
- Sub Item 102 (#3)
- Sub Item 1011 (#4)
- Sub Item 1012 (#5)
Relationships without ID #2
The previous example used the Path
of children to establish a relationship.
But in real life, it's often the other way around.
Usually the children know what parent they belong to.
The following example establishes the relationship based on a Parent Path string:
- In this example, we just add the
parent path
to the list of keys - Since the
own path
is used to establish the relationship, it will find all items which have theown path
as a relationship key
Show Tree of Data
-
Item:
Root Node (id: 1)
-
Sub-Items on field SubItems - found 2
-
Item:
Sub Item 101 (id: 2)
-
Sub-Items on field SubItems - found 2
- Item: Sub Item 1011 (id: 4)
- Item: Sub Item 1012 (id: 5)
-
Sub-Items on field SubItems - found 2
- Item: Sub Item 102 (id: 3)
-
Item:
Sub Item 101 (id: 2)
-
Sub-Items on field SubItems - found 2
Flat List of Items 5
- Root Node (#1)
- Sub Item 101 (#2)
- Sub Item 102 (#3)
- Sub Item 1011 (#4)
- Sub Item 1012 (#5)
Multiple Relationships like Folders and Files
This is a very advanced example, where we create different types of data on different streams and establish relationships.
folder-in:/101
file-in:/101
folder:/
Show Tree of Data
-
Item:
Folder '/' (id: 1)
Parent (field Parent): Folder '/' (id: 1)-
Sub-Items on field Folders - found 2
-
Item:
Folder '/101' (id: 2)
Parent (field Parent): Folder '/101' (id: 2)-
Sub-Items on field Folders - found 2
-
Item:
Folder '/101/1011' (id: 3)
Parent (field Parent): Folder '/101/1011' (id: 3) -
Item:
Folder '/101/1012' (id: 4)
Parent (field Parent): Folder '/101/1012' (id: 4)
-
Item:
Folder '/101/1011' (id: 3)
-
Sub-Items on field Files - found 1
-
Item:
File Text in 101.txt (id: 5)
Parent (field Parent): Folder '/101' (id: 2)
-
Item:
File Text in 101.txt (id: 5)
-
Sub-Items on field Folders - found 2
-
Item:
Folder '/102' (id: 6)
Parent (field Parent): Folder '/102' (id: 6)
-
Item:
Folder '/101' (id: 2)
-
Sub-Items on field Files - found 2
-
Item:
File Test.txt (id: 7)
Parent (field Parent): Folder '/' (id: 1) -
Item:
File Image.jpg (id: 8)
Parent (field Parent): Folder '/' (id: 1)
-
Item:
File Test.txt (id: 7)
-
Sub-Items on field Folders - found 2
Flat List of All Items 8
- Folder '/' (#1)
- Folder '/101' (#2)
- Folder '/101/1011' (#3)
- Folder '/101/1012' (#4)
- File Text in 101.txt (#5)
- Folder '/102' (#6)
- File Test.txt (#7)
- File Image.jpg (#8)
Flat List of Folders 5
- Folder '/' (#1)
- Folder '/101' (#2)
- Folder '/101/1011' (#3)
- Folder '/101/1012' (#4)
- Folder '/102' (#6)
Flat List of Files 5
- Folder '/' (#1)
- Folder '/101' (#2)
- Folder '/101/1011' (#3)
- Folder '/101/1012' (#4)
- Folder '/102' (#6)
Source Code of this file
Below you'll see the source code of the file. Note that we're just showing the main part, and hiding some parts of the file which are not relevant for understanding the essentials. Click to expand the code
@inherits Custom.Hybrid.Razor14 @using ToSic.Razor.Blade; @using System.Linq; @using ToSic.Eav.DataSources; <!-- unimportant stuff, hidden --> <h2>Custom Dynamic DataSources - Data Relationships</h2> <div @Sys.PageParts.InfoWrapper()> @Html.Partial("../shared/DefaultInfoSection.cshtml") <div @Sys.PageParts.InfoIntro()> <p> Data can have relationships to other data, allowith code to navigate from one to the other. </p> </div> </div> Tree Referencing Children The TreeBasic... <!-- unimportant stuff, hidden --> @{ var tree = Kit.Data.GetSource(name: "TreeBasic"); var root = AsDynamic(tree.List.FirstOrDefault(i => i.EntityId == 1)); var rootSubItems = AsList(root.SubItems as object); } <h3>Example Reading some Data</h3> <ul> <li>Root name: @root.Title</li> <li>Root ID: @root.EntityId</li> <li>Item count in <em>field</em> <code>SubItems</code>: @rootSubItems.Count()</li> <li>Title of first child: @rootSubItems.First().EntityTitle</li> <li> Looping through children of Root <ul> @foreach(var child in AsList(root.SubItems as object)) { <li>@child.EntityTitle</li> } </ul> </li> </ul> @Html.Partial("./helpers/Show Tree.cshtml", new { Title = "Show Tree of Data", Root = root, SubNodeNames = "SubItems" }) @Html.Partial("./helpers/Show Data List.cshtml", new { Title = "Flat List of Items", Data = tree }) Tree with Children and Parents The... <!-- unimportant stuff, hidden --> @{ tree = Kit.Data.GetSource(name: "TreeBasicWithParents"); root = AsDynamic(tree.List.FirstOrDefault(i => i.EntityId == 1)); } @Html.Partial("./helpers/Show Tree.cshtml", new { Title = "Show Tree of Data", Root = root, SubNodeNames = "SubItems", ParentField = "Parent" }) @Html.Partial("./helpers/Show Data List.cshtml", new { Title = "Flat List of Items", Data = tree }) Relationships without ID #1 The previous... <!-- unimportant stuff, hidden --> @{ tree = Kit.Data.GetSource(name: "TreeChildPaths"); root = AsDynamic(tree.List.FirstOrDefault(i => i.EntityId == 1)); } @Html.Partial("./helpers/Show Tree.cshtml", new { Title = "Show Tree of Data", Root = root, SubNodeNames = "SubItems", ParentField = "Parent" }) @Html.Partial("./helpers/Show Data List.cshtml", new { Title = "Flat List of Items", Data = tree }) Relationships without ID #2 The previous... <!-- unimportant stuff, hidden --> @{ tree = Kit.Data.GetSource(name: "TreeParentPaths"); root = AsDynamic(tree.List.FirstOrDefault(i => i.EntityId == 1)); } @Html.Partial("./helpers/Show Tree.cshtml", new { Title = "Show Tree of Data", Root = root, SubNodeNames = "SubItems", ParentField = "Parent" }) @Html.Partial("./helpers/Show Data List.cshtml", new { Title = "Flat List of Items", Data = tree }) Multiple Relationships like Folders and... <!-- unimportant stuff, hidden --> @{ tree = Kit.Data.GetSource(name: "TreeFoldersAndFiles"); root = AsDynamic(tree.List.FirstOrDefault(i => i.EntityId == 1)); } @Html.Partial("./helpers/Show Tree.cshtml", new { Title = "Show Tree of Data", Root = root, SubNodeNames = "Folders,Files", ParentField = "Parent" }) @Html.Partial("./helpers/Show Data List.cshtml", new { Title = "Flat List of All Items", Data = tree }) @Html.Partial("./helpers/Show Data List.cshtml", new { Title = "Flat List of Folders", Data = tree["Folders"] }) @Html.Partial("./helpers/Show Data List.cshtml", new { Title = "Flat List of Files", Data = tree["Folders"] }) @* Footer *@ @Html.Partial("../Shared/Layout/FooterWithSource.cshtml", new { Sys = Sys })