> ## Documentation Index
> Fetch the complete documentation index at: https://learn.nextedy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Expand Navigation Properties

> Load related entities through expansion paths in your Nextedy POWERSHEET source configuration to display hierarchical data across multiple entity types in a single sheet.

export const LastReviewed = ({date}) => {
  if (!date) return null;
  const formatted = new Date(`${date}T00:00:00Z`).toLocaleDateString("en-US", {
    year: "numeric",
    month: "long",
    day: "numeric",
    timeZone: "UTC"
  });
  return <p className="mt-10 text-sm text-gray-400 dark:text-zinc-500 not-prose">
      Last reviewed on {formatted}
    </p>;
};

## Prerequisites

Before configuring expansion paths, ensure you have:

* A [data model](/powersheet/guides/data-model/index) with entity types and relationships defined
* A [sheet configuration](/powersheet/guides/sheet-configuration/index) with at least one source
* Familiarity with [writing entity queries](/powersheet/guides/queries/write-entity-query)

## How Expansion Connects Model, Source, and Columns

The three configuration layers -- **data model**, **sheet sources**, and **sheet columns** -- connect through navigation property names. The data model defines entity types and relationships. Sources define how to query and expand those relationships. Columns define how to display the resulting data.

The **cardinality** of a relationship determines the expand pattern and the column binding syntax.

<Frame>
  <img src="https://mintcdn.com/none-17b4493f/3Zik2OH750CE3kB4/powersheet/diagrams/guides/queries/expand-navigation-properties/diagram-1.svg?fit=max&auto=format&n=3Zik2OH750CE3kB4&q=85&s=29992535c2d0773a1d9b45536519a232" alt="diagram" style={{ width: "600px", maxWidth: "100%" }} width="600" height="200" data-path="powersheet/diagrams/guides/queries/expand-navigation-properties/diagram-1.svg" />
</Frame>

## Shared Data Model for Examples

All examples below use this data model:

```yaml theme={null}
domainModelTypes:
  Chapter:
    polarionType: heading

  UserNeed:
    polarionType: user_need
    properties:
      description:
      severity:

  SystemRequirement:
    polarionType: sys_req
    properties:
      description:
      severity:

  DesignRequirement:
    polarionType: des_req
    properties:
      description:

relationships:
  - from: UserNeed
    to: Chapter
    cardinality: many-to-one
    storage: linkedWorkItems
    linkRole: parent
    direct:
      name: chapter
    back:
      name: userNeeds

  - from: SystemRequirement
    to: UserNeed
    cardinality: many-to-many
    storage: linkedWorkItems
    linkRole: decomposes
    direct:
      name: userNeeds
    back:
      name: systemRequirements
```

Each relationship defines a `direct` and `back` navigation direction. The `direct` side navigates from the `from` entity toward the `to` entity. The `back` side navigates in reverse.

<Steps>
  <Step title="Expand a Many-to-One Relationship (N:1)">
    **Scenario:** Each `UserNeed` belongs to exactly one `Chapter`. Use the `direct` direction -- the navigation property `chapter` (singular, scalar).

    Add the expand to your source configuration:

    ```yaml theme={null}
    sources:
      - id: user_needs
        query:
          from: UserNeed
        expand:
          - name: chapter
    ```

    Then bind columns to the expanded entity:

    ```yaml theme={null}
    columns:
      title:
        title: Title
        hasFocus: true
      chapter:
        title: Chapter
        display: title
        list:
          search:
            - title
      chapter.title:
        title: Chapter Title
        isReadOnly: true
    ```

    * `chapter` -- renders a single-value reference picker (scalar navigation property)
    * `chapter.title` -- displays the referenced Chapter's title as a read-only column
  </Step>

  <Step title="Expand a One-to-Many Relationship (1:N)">
    **Scenario:** Each `Chapter` has multiple child `UserNeed` items. Use the `back` direction -- the navigation property `userNeeds` (plural, collection).

    ```yaml theme={null}
    sources:
      - id: chapters
        query:
          from: Chapter
        expand:
          - name: userNeeds
    ```

    ```yaml theme={null}
    columns:
      title:
        title: Chapter
        hasFocus: true
      userNeeds:
        title: Title
        hasFocus: true
    ```

    * `userNeeds` -- expands into child rows in the sheet, creating a new grid level
    * No dot-notation is needed; the expand directly opens the child level beneath each parent row
  </Step>

  <Step title="Expand a Many-to-Many Relationship (M:N)">
    **Scenario:** `UserNeed` items are linked to multiple `SystemRequirement` items and vice versa. Many-to-many relationships use an **association entity** between the two types.

    The source expand requires **two levels** -- first to the association entity, then through to the target entity:

    ```yaml theme={null}
    sources:
      - id: user_needs
        query:
          from: UserNeed
        expand:
          - name: systemRequirements
            expand:
              - name: systemRequirement
    ```

    Column bindings use dot-notation to traverse both levels:

    ```yaml theme={null}
    columns:
      title:
        title: Title
        hasFocus: true
      systemRequirements.systemRequirement:
        title: System Requirement
        list:
          search:
            - objectId
            - title
          createNew: true
      systemRequirements.systemRequirement.title:
        title: SysReq Title
        hasFocus: true
    ```

    * `systemRequirements` -- navigates to the association entity
    * `systemRequirements.systemRequirement` -- navigates through to the target `SystemRequirement` entity, acting as a multi-item reference picker
    * `systemRequirements.systemRequirement.title` -- displays the target entity's title

    <Warning title="Two-level expand is required for M:N">
      A many-to-many relationship always uses an intermediate association entity. If you only expand one level (`- name: systemRequirements` without the nested `- name: systemRequirement`), you will see the association entities rather than the target items.
    </Warning>
  </Step>

  <Step title="Build Deep Multi-Level Hierarchies">
    You can nest expansion paths to any depth. For a full requirements traceability matrix (RTM), chain expansions across multiple entity types:

    ```yaml theme={null}
    sources:
      - id: rtm
        query:
          from: UserNeed
        expand:
          - name: systemRequirements
            expand:
              - name: systemRequirement
                expand:
                  - name: designRequirements
                    expand:
                      - name: designRequirement
    ```

    Each nested level adds another tier of child rows in the sheet. Columns at each level bind to their respective entity type properties.

    <Tip title="Keep expansion depth manageable">
      Each expansion level triggers additional queries to fetch related entities. For large datasets, limit expansion to 2-3 levels and consider using [query optimization techniques](/powersheet/guides/queries/optimize-queries) to maintain performance.
    </Tip>
  </Step>

  <Step title="Apply Document-Scoped Expansion">
    Constrain expanded entities to the current document by adding `constraints` to the source:

    ```yaml theme={null}
    sources:
      - id: main
        query:
          from: UserNeed
        constraints:
          applyCurrentDocumentTo: SystemRequirement
        expand:
          - name: systemRequirements
            expand:
              - name: systemRequirement
    ```

    The `applyCurrentDocumentTo` constraint filters expanded `SystemRequirement` entities to only include those from the same Polarion document context. This is useful when your document contains a scoped subset of work items and you want expansions to respect that boundary.
  </Step>
</Steps>

## Cardinality Quick Reference

| Cardinality | Model definition                                             | Source expand                                                 | Column binding                         | UI behavior                   |
| ----------- | ------------------------------------------------------------ | ------------------------------------------------------------- | -------------------------------------- | ----------------------------- |
| **N:1**     | `cardinality: many-to-one`, `direct.name: chapter`           | `- name: chapter`                                             | `chapter`, `chapter.title`             | Single-value reference picker |
| **1:N**     | Reverse of N:1, `back.name: userNeeds`                       | `- name: userNeeds`                                           | `userNeeds`                            | Child rows (new grid level)   |
| **M:N**     | `cardinality: many-to-many`, `back.name: systemRequirements` | `- name: systemRequirements` then `- name: systemRequirement` | `systemRequirements.systemRequirement` | Multi-item reference picker   |

## Common Pitfalls

<Warning title="Navigation property names are case-sensitive">
  Property names must exactly match the `direct.name` or `back.name` values in your data model. A misspelled property name causes the expansion to silently return no related entities. Verify names in **Administration > Nextedy Powersheet > Models**.
</Warning>

<Warning title="Don't confuse direct and back directions">
  The `direct` direction follows the relationship as declared (from the `from` type to the `to` type), while `back` reverses it. Using the wrong direction returns an empty result set. Check the relationship definition to confirm which navigation property name belongs to which direction.
</Warning>

<Tip title="Use read-only columns for expanded scalar properties">
  When displaying properties from an expanded entity (e.g., `chapter.title`), set `isReadOnly: true` on the column. This prevents users from attempting to edit values that belong to a different entity type.
</Tip>

<Tip title="Match column bindings to expand paths">
  For a column binding like `systemRequirements.systemRequirement.title` to display data, the source must include a matching expand entry with `name: systemRequirements` and nested `name: systemRequirement`. Missing or mismatched expansions result in empty columns.
</Tip>

## Verify Your Configuration

After saving your sheet configuration:

1. Open the Polarion document that uses this sheet configuration
2. You should now see nested rows under each parent entity corresponding to the expanded navigation properties
3. For N:1 expansions, verify the reference picker column shows the correct related entity
4. For 1:N expansions, verify child rows appear beneath each parent
5. For M:N expansions, verify the dot-notation columns display target entity properties through both expand levels

If no expanded rows appear, check the navigation property names against your data model and confirm that linked work items exist in Polarion for the relationship.

## See Also

* [Write an Entity Query](/powersheet/guides/queries/write-entity-query) -- basics of the `from` clause and query structure
* [Configure a Relationship](/powersheet/guides/data-model/configure-relationship) -- how to define relationships with `direct` and `back` names
* [Configure Many-to-Many Relationships](/powersheet/guides/data-model/configure-many-to-many) -- association entity setup for M:N links
* [Create Bidirectional Links](/powersheet/guides/data-model/create-bidirectional-links) -- linking entities in both directions
* [Configure Multi-Item Column](/powersheet/guides/sheet-configuration/configure-multi-item-column) -- column settings for collection bindings
* [Configure Sources](/powersheet/guides/sheet-configuration/configure-sources) -- full source configuration reference
* [Optimize Queries](/powersheet/guides/queries/optimize-queries) -- performance tips for deep expansion paths
* [Filter by Document](/powersheet/guides/queries/filter-by-document) -- apply document constraints to queries

<LastReviewed date="2026-07-02" />
