Learn how to build self-referential parent-child hierarchies in Dataverse, configure hierarchical security so managers automatically inherit access to subordinates' records, set up multi-level rollup aggregation, and display interactive tree visualizations in model-driven apps. This expert-level lesson covers the architecture, edge cases, and performance trade-offs you need to get it right.

Imagine you're building a field service management system for a national utilities company. Technicians report to supervisors, supervisors report to regional managers, and regional managers report to a national operations director. Each level needs to see its own records and the records of everyone below it — but not sideways, and definitely not upward. Meanwhile, you want a rollup column that automatically sums the total estimated repair hours across every job in a supervisor's entire team tree. And you want to display the organizational structure as an actual interactive hierarchy in the model-driven app so dispatchers can visually navigate it.
This is the moment when most Power Platform developers realize that standard security roles and lookup relationships won't cut it. You need Dataverse's hierarchical features: self-referential parent relationships, hierarchical security, the Manager hierarchy or Custom hierarchy models, and the tree visualization control built into model-driven apps. Getting these right requires understanding not just the configuration steps but the architectural decisions underneath — because mistakes at this level are expensive to unwind.
By the end of this lesson, you'll be able to design self-referential hierarchies in Dataverse, configure hierarchical security so managers automatically inherit access to their reports' records, wire up rollup columns that aggregate data across the entire subtree, and display navigable tree structures in your model-driven app. You'll also understand where each approach breaks down and how to architect around those limits.
What you'll learn:
You should be comfortable with the core Dataverse concepts covered in Dataverse Fundamentals: Tables, Columns, and Rows Explained for Power Apps Makers. You should understand one-to-many relationships and cascade behaviors — if those feel shaky, review Configuring Dataverse Table Relationships in Model-Driven Apps: One-to-Many, Many-to-Many, and Cascade Behaviors Explained first. You should also have a working understanding of Dataverse security roles and business units, as covered in Dataverse Security: Business Units, Security Roles, and Teams. Familiarity with rollup columns will help; if you need a primer, see Formula Columns and Rollup Columns in Dataverse: Calculated Data Without Code.
Before writing a single line of configuration, you need to understand the three distinct features that the word "hierarchical" covers in Dataverse. Conflating them is the most common source of confusion.
Hierarchical relationships are self-referential one-to-many relationships on a single table. A row of type Account can have a parent Account. A row of type Position can have a parent Position. The relationship column points back to the same table. This is purely a data modeling concept — it defines the tree structure in your data.
Hierarchical security is a security model that uses either the system User table's manager chain or a custom hierarchical relationship on a custom table to automatically grant a manager read (and optionally write) access to records owned by their direct and indirect reports. This is a security enforcement concept.
Hierarchy visualization is a UI feature in model-driven apps that renders rows in a tree diagram so users can navigate parent-child relationships visually. This is a presentation concept.
These three things are related but independent. You can have a hierarchical relationship without using hierarchical security. You can use hierarchical security with the built-in Manager model without any custom hierarchical relationship. You can enable hierarchy visualization on any self-referential relationship. Understanding which problem each feature solves prevents you from over-engineering a solution.
The instinct for many developers coming from relational backgrounds is to create a separate junction or tree table. Resist this for most organizational hierarchy scenarios. Dataverse's hierarchical features (both security and visualization) require a self-referential lookup column on a single table — a column on the table that points to another record of the same table type.
The benefits of the self-referential model:
The limitation: each row can have only one parent (it's a tree, not a graph). If your business domain requires a row to belong to multiple parent hierarchies, you need a different approach — but that's a relatively rare requirement for organizational structures.
Let's use a concrete scenario: a Service Region table that represents geographic coverage zones, where regions can contain sub-regions to arbitrary depth (National → Regional → District → Local).
In Power Apps maker portal, navigate to your solution, find the Service Region table, and go to the Relationships tab.
Create a new Many-to-One relationship where:
new_parentregionidWhen you set the related table to the same table you're currently editing, Dataverse knows this is a potential hierarchy candidate.
Note
Dataverse limits each table to exactly one designated hierarchical relationship. If you create multiple self-referential lookups, only one can be flagged as the hierarchy. Choose thoughtfully — this designation affects which relationship the visualization control uses and which one drives hierarchical rollup aggregation.
After creating the relationship, go back to the relationship definition and look for the Hierarchical checkbox or toggle (labeled "Hierarchical relationship" in the classic interface, or toggled under the relationship properties in the modern maker portal). Enable it. This is the single most important step — without it, you have a self-referential lookup but Dataverse doesn't treat it as a formal hierarchy.
For hierarchical relationships, cascade behavior deserves careful thought. The default Parental cascade behavior means that when you delete a parent region, Dataverse will cascade delete all child regions. For organizational structures, this is usually dangerous — deleting a district shouldn't wipe out all its local regions.
Instead, consider Referential with a Restrict delete behavior: attempting to delete a parent that still has children raises an error and prevents the deletion. This forces a deliberate restructuring before removal, which is usually the correct behavior for organizational trees.
Warning
If you set the cascade behavior to Parental on a deep hierarchy, a single delete at the top can trigger hundreds or thousands of cascading deletes across child rows. For a Service Region table with 5,000 rows spread across 4 levels, this could cause a timeout or a partially completed delete operation that leaves your data in an inconsistent state. Use Restrict or Referential behaviors for hierarchical tables unless you have a specific reason for cascade deletion.
A tempting shortcut is to add a Region Type choice column (National, Regional, District, Local) and use it instead of a true parent relationship. Don't do this. The flat-flag pattern breaks down immediately when:
The true self-referential relationship handles all of these gracefully. Keep the type column if it helps with filtering or business logic, but the parent relationship should be the source of truth for the structure.
Complex enterprise apps sometimes need two or more hierarchy dimensions on the same entity. For example, a workforce management app might need:
Since only one self-referential relationship can be the designated hierarchy, you have two options:
Option A: Separate tables. Create an Org Chart Node table and a Cost Center table, each with their own hierarchical relationship. Relate the primary entity (like Worker) to both. This is architecturally clean but requires more complex querying.
Option B: Hierarchical for the primary, custom rollup logic for the secondary. Mark the org chart relationship as the hierarchy. For cost centers, build rollup logic using Power Automate cloud flows or calculated columns that traverse the cost center lookup manually. This is less elegant but keeps everything in one primary table.
For most scenarios, Option A is preferable because it keeps each hierarchy clean and queryable independently.
Key insight
The hierarchical designation on a relationship is not just a UI toggle — it creates internal Dataverse indexes optimized for hierarchical queries using the Above, AboveOrEqual, Under, UnderOrEqual, and NotUnder query operators in FetchXML and the Dataverse SDK. These operators can traverse the entire tree in a single query. Without the designation, you'd need recursive queries — a significant performance difference on deep trees.
This is where things get genuinely powerful — and genuinely complex. Hierarchical security in Dataverse means that a user positioned higher in a hierarchy automatically gets read access (and optionally write access) to records owned by users below them, without needing explicit record sharing.
Dataverse offers two distinct models for hierarchical security:
Manager Hierarchy: Uses the Manager field on the system User (SystemUser) table. When you set User A's manager to User B, User B automatically gets hierarchical access to records owned by User A. This model is straightforward and ties directly to your Azure Active Directory org chart if you sync manager relationships through Entra ID. The downside: it's entirely based on the User table's built-in manager field. You cannot use a custom table's hierarchy for this model.
Custom Hierarchy (Position Hierarchy): Uses the Position table (which is a system table in Dataverse), which has a built-in hierarchical self-reference. Users are assigned to positions, positions have parent positions, and the hierarchy is inferred from the position tree. This model is more flexible because the position hierarchy can be structured differently from the actual manager chain — useful when organizational security domains don't match the org chart exactly.
Tip
The Manager Hierarchy is the right choice when your security model should mirror the actual organizational reporting chain, especially if you're syncing managers from Entra ID via Azure AD Connect. Choose the Custom (Position) Hierarchy when security domains and org charts diverge — for example, when a "Regional Security Officer" role needs access to all records in a region regardless of who they formally report to.
To enable this feature, navigate to the Power Platform Admin Center, select your environment, go to Settings → Users + Permissions → Hierarchical Security. Here you'll find:
The depth setting is critical and often overlooked. A depth of 3 means a manager can see records owned by users up to 3 levels below them. If your org has 6 levels and you leave depth at 3, vice presidents won't see the records of front-line technicians. Set depth to match your deepest hierarchy level, but understand the performance implication: larger depths mean Dataverse evaluates more users when checking record access.
Hierarchical security doesn't replace your standard security roles — it augments them. A user must still have a security role that grants at least User level access to a table. The hierarchical security then extends that to include records owned by subordinates up to the configured depth.
The permission levels involved:
Configure this in the Hierarchical Security settings section in the admin center, where you can specify whether managers get Read Only or Read-Write access to subordinate records.
A concrete example: You have a Service Job table. A Field Technician with User-level access can see their own jobs. You configure hierarchical security at depth 4. Now their supervisor, who has the same security role (User-level), automatically sees all jobs owned by every technician under them in the hierarchy — no additional security role configuration, no record sharing, no views filtered by team membership.
Warning
Hierarchical security only applies to records where the owner is a user (not a team). If your records are team-owned, hierarchical security won't propagate access based on the manager chain. You'll need to use team-based sharing or ensure records are user-owned for this feature to work as expected. This is a fundamental limitation that catches many implementations off guard.
Hierarchical security is elegant for "I should see everything my subordinates own" scenarios, but breaks down in several common cases:
Cross-hierarchy visibility: A compliance officer who needs to see records across multiple branches of the hierarchy. Solution: use record sharing or a broader security role with Business Unit-level access for those specific users.
Non-ownership-based access: If access should be based on a field value (the territory assigned to a job) rather than who owns the record. Solution: combine hierarchical security with custom business logic, or use a different access pattern like security roles with filters.
Temporary delegation: An employee covering for a colleague while on leave. Hierarchical security doesn't support time-bounded access. Solution: explicit record sharing with an expiration convention enforced by a flow.
For these patterns, you'll typically combine hierarchical security with the field-level and record-sharing capabilities covered in Column-Level Security and Record Sharing in Dataverse.
Once your hierarchical relationship is in place and designated as the hierarchy, rollup columns gain a superpower: they can aggregate across the entire subtree, not just direct children.
A standard rollup column on the Account table might sum the revenue of all directly related Opportunities. A hierarchical rollup on the Account table sums the revenue of Opportunities related to the account and all of its descendant accounts, to any configured depth.
This distinction matters enormously for our Service Region scenario. If you want a District region's Total Estimated Hours to reflect the sum of all jobs across every Local region beneath it, you need a hierarchical rollup — a standard rollup would only capture jobs directly on the District record itself.
Navigate to your Service Region table, add a new column, and select Rollup as the column type. As described in Formula Columns and Rollup Columns in Dataverse: Calculated Data Without Code, rollup columns have three sections: Source, Filter, and Aggregate.
For a hierarchical rollup, the key is in the Source section. You'll see the option to specify a relationship — and if your table has a designated hierarchical relationship, you'll see a Hierarchy option in the relationship type selector. Choose Hierarchy (all levels below) rather than a specific one-to-many relationship.
The configuration:
Source Entity: Service Region (self, all hierarchical descendants)
Related Entity: Service Job (via Service Region lookup)
Aggregate Function: SUM
Aggregate Column: Estimated Hours
Filter: Status = Active
When this rollup recalculates, Dataverse traverses the entire subtree beneath each region, finds all related Service Jobs across every descendant region, applies the Active status filter, and sums the hours.
Tip
Rollup columns recalculate asynchronously on a system-defined schedule (typically every 12 hours) or when manually triggered via the "Recalculate" button on a form. For near-real-time aggregates, you'll need to trigger recalculation explicitly using Power Automate or the Dataverse API's CalculateRollupField message. Don't design a user experience that assumes rollup values are always current — communicate the "as of" timing to users.
Hierarchical rollups have a maximum depth of 10 levels. If your tree exceeds 10 levels, the rollup stops at level 10 and doesn't aggregate beyond that. This is a hard platform limit.
Performance considerations for rollups on large hierarchies:
For high-volume scenarios, consider whether a Power Automate flow that explicitly calculates and writes the aggregate on a scheduled basis gives you more control than the native rollup mechanism. The native rollup is elegant for moderate data volumes; for millions of rows, custom aggregation gives you scheduling control and can run incrementally.
Understanding how to query hierarchical data programmatically is essential for building custom views, reports, and integrations. Dataverse provides native FetchXML operators for hierarchical queries that are far more efficient than recursive loops.
Dataverse adds five condition operators specifically for hierarchical queries:
above: Returns all ancestors of a specified row (all rows above it in the tree)eq-or-above: Returns the row itself and all ancestorsunder: Returns all descendants of a specified row (the entire subtree below it)eq-or-under: Returns the row itself and its entire subtreenot-under: Returns all rows that are NOT descendants of a specified rowThese operators work only on the column designated as the hierarchical relationship — not on arbitrary lookup columns.
A FetchXML query to get all Service Jobs belonging to Service Regions under a specific region (say, the "Southwest Region" with a known GUID):
<fetch>
<entity name="new_servicejob">
<attribute name="new_name" />
<attribute name="new_estimatedhours" />
<attribute name="new_status" />
<link-entity name="new_serviceregion"
from="new_serviceregionid"
to="new_serviceregionid"
alias="region">
<filter>
<condition attribute="new_parentregionid"
operator="eq-or-under"
value="{12345678-1234-1234-1234-123456789abc}" />
</filter>
</link-entity>
</entity>
</fetch>
Notice that the condition is on new_parentregionid — the hierarchical lookup column — and the operator eq-or-under traverses the entire subtree including the specified region itself.
This single query replaces what would otherwise be a recursive series of queries. The performance advantage is substantial: a recursive approach on a 6-level deep hierarchy with 100 nodes per level would require up to 7 separate queries (one per level). The eq-or-under operator does it in one.
In a Power Automate flow using the Dataverse connector, you can't directly write FetchXML in the "List rows" action's filter fields — but you can use the List rows action with a custom FetchXML via the "Fetch XML query" parameter (visible when you switch to advanced mode or use the "Fetch XML query" field directly in the newer connector).
Paste the FetchXML directly into that field, parameterizing the GUID:
<fetch>
<entity name="new_serviceregion">
<attribute name="new_serviceregionid" />
<attribute name="new_name" />
<filter>
<condition attribute="new_parentregionid"
operator="under"
value="@{triggerOutputs()?['body/new_serviceregionid']}" />
</filter>
</entity>
</fetch>
This pattern is extremely useful for building notification flows, data synchronization, or delegation logic that needs to operate on "everyone below this manager."
Now for the part that makes the hierarchy tangible to users: the tree visualization control. When configured correctly, this gives users a clickable, pannable tree diagram where they can see the entire hierarchy of records, navigate to any node, and understand organizational structure at a glance.
The hierarchy visualization control is enabled at the view level, not the form level. Navigate to your solution, open the Service Region table, and go to the Views tab.
You don't create a special "hierarchy view" — instead, you enable hierarchy visualization on an existing public view. Open or create a view for Service Region (something like "All Service Regions"). In the view editor, look for the Hierarchy Settings option (in the classic solution explorer, this is under Settings → Hierarchy Settings; in the modern maker portal, look in the view's ellipsis/more options menu for "Hierarchy Settings").
In Hierarchy Settings, configure:
After enabling, when users navigate to the Service Region list view, they'll see a toggle button to switch between the grid view and the hierarchy view. The hierarchy view renders an interactive tree where each node shows the configured columns and clicking a node opens the quick view form — and from there, the full record form.
Tip
Design your hierarchy quick view form specifically for the tree context. It should show at most 4-5 key fields — things like Region Name, Region Manager, Active Job Count, Total Estimated Hours. A full-featured form with 20+ fields overwhelms the compact quick-view panel. Designing Model-Driven Forms: Sections, Tabs, Subgrids, and Quick View Forms covers quick view form design in detail.
The tree renders top-down. The root node (a region with no parent) appears at the top. Branches expand downward. Users can expand/collapse nodes, pan the diagram, and click nodes to see details.
Limitations you should communicate to stakeholders before promising features:
For requirements that exceed these limits — custom node colors, actions directly on tree nodes, infinite tree depth, performance beyond 1,500 nodes — you'll need a custom Power Apps Component Framework (PCF) control. This is a significant build investment but gives you complete control over the tree rendering. You can learn more about that path in Extending Model-Driven Apps with PCF Controls: Building and Deploying Custom Field and Dataset Components for Dataverse Forms and Views.
One practical challenge with hierarchy views: users don't naturally discover the toggle between grid and hierarchy view on their own. Address this through:
The toggle is visible once you know to look for it, but first-time users consistently miss it. Make it prominent.
Let's put everything together with our field service scenario and trace through how all three features interact.
Tables:
Service Region (hierarchical self-reference on Parent Region)Service Job (many-to-one to Service Region, owner is a User)Hierarchy structure:
National Operations (Level 1)
├── Southwest Region (Level 2)
│ ├── Arizona District (Level 3)
│ │ ├── Phoenix Local (Level 4)
│ │ └── Tucson Local (Level 4)
│ └── Nevada District (Level 3)
└── Northwest Region (Level 2)
└── ...
Users and their positions in the org:
You've enabled Manager Hierarchy security at depth 4. Carla's security role gives her User-level read on Service Jobs (she can see her own). Via hierarchical security, she also gets read access to all Service Jobs owned by Darnell, Priya, and all technicians under Priya — automatically, with no record sharing required.
Priya can see her own jobs and all her technicians' jobs (depth 2). She can't see Darnell's jobs (upward access is never granted by hierarchical security). She can't see jobs in the Nevada District (sideways access is never granted).
This access pattern — downward visibility, no upward, no sideways — is exactly what most organizational security models need, and it's maintained automatically as the org chart changes. When you add a new technician under Priya in Entra ID, the next time their manager field syncs, Priya automatically gains access to their records.
On the Service Region table, you've configured a hierarchical rollup column Total Estimated Hours that sums the Estimated Hours column from all Service Jobs related to any Service Region in the subtree.
When you view the Arizona District record, Total Estimated Hours shows the sum of all active jobs from Phoenix Local AND Tucson Local AND any jobs directly attached to the Arizona District record itself. The rollup traverses all four hierarchy levels automatically.
When Priya looks at the Arizona District in the hierarchy tree view, she can see this aggregate without navigating into each local region. This is the direct business value: middle managers get rolled-up visibility without having to drill down manually.
Key insight
The hierarchical rollup and hierarchical security are independent mechanisms. The rollup operates on the data hierarchy (Service Region tree). The security operates on the user hierarchy (Manager chain). They're configured separately and can be set to different depths. Don't assume they're connected just because they both use the word "hierarchical."
With hierarchy visualization enabled on the Service Region table's "All Service Regions" view, Darnell logs in and switches to hierarchy view. He sees the Southwest Region node at the top of his visible tree, with Arizona District and Nevada District as children, and the four local regions beneath those. The quick view form on each node shows region name, assigned manager name, and the Total Estimated Hours rollup value.
He can immediately see that Tucson Local has 340 estimated hours this month while Phoenix Local has 85, without clicking into any individual records. That operational insight comes directly from the combination of hierarchical rollup data and hierarchy visualization — neither feature alone delivers it.
In this exercise, you'll build a minimal version of the Service Region hierarchy with security and visualization in a non-production environment.
Create a new solution in your development environment. Add a new custom table: Service Region with the display name "Service Region" and schema name new_serviceregion.
Add the following columns to Service Region:
Region Name (Text, Required, max 100 chars) — this will become your primary name columnRegion Type (Choice: National, Regional, District, Local)Region Manager (Lookup to User/SystemUser table)Total Estimated Hours — leave this for the rollup stepCreate the self-referential relationship: go to Relationships on the Service Region table, add a Many-to-One relationship where the related table is also Service Region. Name the lookup column "Parent Region" (new_parentregionid). Set delete behavior to Restrict. Save.
Edit the relationship you just created and enable the Hierarchical toggle. Save.
Create a companion table: Service Job with columns Job Name (Text), Estimated Hours (Whole Number), Service Region (Lookup to Service Region), and Status (Choice: Active, Closed).
On the Service Region table, add a new Rollup column Total Estimated Hours. Configure it to aggregate from Service Job via the Service Region lookup, SUM the Estimated Hours, filtering for Active status. Enable the Hierarchy option if available in your version (if not, a non-hierarchical rollup against direct children is still useful for the exercise).
Add several Service Job records attached to your local-level regions. Manually trigger recalculation on a district region and observe whether the hours from child regions roll up.
Navigate to the Service Region table's views. Open or create an "All Service Regions" public view that includes Region Name and Region Type columns.
Access Hierarchy Settings for this view. Select the Parent Region hierarchical relationship. Create or select a quick view form for Service Region that shows Region Name, Region Type, and Total Estimated Hours. Save the hierarchy settings.
Open your model-driven app, navigate to Service Regions, and toggle to the hierarchy view. Navigate the tree and click a node to verify the quick view appears.
The hierarchy visualization toggle only appears on views of tables that have an active designated hierarchical relationship. Verify two things: (1) you've created a self-referential relationship on the table, and (2) you've enabled the Hierarchical flag on that specific relationship. If both are true and the toggle still doesn't appear, clear your browser cache and check whether your security role includes read access to the hierarchical relationship's metadata.
The most common causes:
Rollup columns are asynchronous. The value won't update immediately when child records change. Check:
If you have more than 1,500 records in the table, the tree truncates. The nodes shown are not guaranteed to be a specific subset — the truncation isn't "top of tree first" in all cases.
If you're under 1,500 records but still see missing nodes, verify that all records have the parent lookup populated correctly. Orphaned records (parent lookup pointing to a deleted record) won't appear in the tree in a predictable location.
The under, above, and related operators only work on the column that is designated as the hierarchical column. If you query against new_parentregionid on a table where new_parentregionid is NOT flagged as the hierarchical relationship, the operators will silently return no results rather than throwing an error. Verify the hierarchical flag is set correctly.
Warning
When you export and import a solution containing a table with a hierarchical relationship, the hierarchical designation sometimes doesn't transfer correctly in older managed solution layers. After importing to a target environment, verify the hierarchical flag is still enabled on the relationship. This is a known issue in certain Power Platform versions — add a post-deployment verification step to your deployment runbook.
Business units are Dataverse's primary security boundary mechanism. Hierarchical security is supplemental. If your organization's security model maps cleanly to business units (e.g., each region is a business unit), you may not need hierarchical security at all — standard Business Unit-level access on security roles accomplishes the same thing with less complexity.
Use hierarchical security when:
Use business units when:
For a deeper discussion of business unit design, Model-Driven App Security: Configuring Security Roles, Field Permissions, and Team-Based Access for Table Data covers the interaction between business units, teams, and roles in detail.
Hierarchical security performance degrades quadratically as both depth and breadth increase. Each time a user requests access to a record, Dataverse evaluates the hierarchical chain. At depth 4 with 20 direct reports per manager, a single access check may evaluate hundreds of user records.
For environments with more than 5,000 users participating in hierarchical security, monitor your environment's access check latency. Signs of degradation: slowly loading views that should be fast, timeouts on record retrieval in workflows. Mitigations:
From a query performance perspective, a flat-wide hierarchy (many children at one level, shallow depth) performs better than a tall-narrow hierarchy (few children per level, deep depth). The hierarchical query operators traverse depth at query time, so deeper hierarchies mean more traversal work.
If your domain naturally produces deep chains (e.g., project tasks with recursive subtasks 8-10 levels deep), benchmark your FetchXML hierarchy queries with realistic data volumes before committing to the design. A depth of 10 on a table with 100,000 rows can produce noticeably slow queries.
You've now covered the full landscape of Dataverse hierarchical features. Here's the architecture in summary:
The self-referential hierarchical relationship is your foundation — one designated relationship on a table that creates the tree structure Dataverse understands natively. The hierarchical designation on that relationship unlocks everything else: efficient FetchXML operators, hierarchical rollup aggregation, and the hierarchy visualization control.
Hierarchical security (either Manager or Custom/Position model) layers access control on top of the data hierarchy by automatically propagating record visibility downward through a user hierarchy. It's powerful for organizational security models but has firm boundaries: user-owned records only, a maximum depth limit that must be configured correctly, and a delay before changes propagate to existing records.
Hierarchical rollup columns aggregate data across the entire subtree — not just direct children — giving you multi-level reporting without custom code. They're asynchronous and have a 10-level depth limit, so plan your user experience accordingly.
Hierarchy visualization in model-driven apps gives users an interactive tree browser. It's excellent for organizational navigation up to 1,500 records; beyond that or for conditional formatting requirements, a custom PCF control becomes necessary.
The most important design decisions are: which relationship gets the hierarchical designation (you only get one), which security model fits your org structure (Manager vs. Custom), and whether your security boundary is better served by business units, hierarchical security, or a combination.
For your next steps in this learning path, explore how your hierarchical data model interacts with the broader app experience. The data model decisions you've made here flow directly into how you design your forms — see Designing Model-Driven Forms: Sections, Tabs, Subgrids, and Quick View Forms for how to surface hierarchical context on the record forms themselves. And when you're ready to go beyond the built-in visualization limits, Extending Model-Driven Apps with PCF Controls: Building and Deploying Custom Field and Dataset Components for Dataverse Forms and Views shows you how to build a fully custom tree component that can handle the scenarios the native control can't.