When working with virtual tables, especially those backed by SharePoint lists, the behaviour you’re seeing is expected. The reason filterResults.size returns 1 but the other columns are blank is because:
Liquid filtering does not perform type‑coercion on virtual table attributes.
Even though you converted the ID to a decimal, the value inside the virtual table entity is not a true decimal, but a string representation coming from the SharePoint connector.
So the comparison:
| where: "msdyn_externalprimarykey", formattedId
matches the row by key, but the returned entity object does not hydrate the other attributes because the filter is not executed server‑side — it’s a Liquid in‑memory filter.
This is a known limitation with virtual tables + Liquid.
Why the attributes are blank
Virtual tables only return full attribute data when the FetchXML query itself includes a filter that matches the row.
When you filter after the query using Liquid:
queryB.results.entities | where: ...
…the platform does not re‑query the virtual table provider.
It simply filters the already‑returned rows, and virtual table rows often contain only the primary key unless the provider returns full data.
This is why:
The attributes were never populated.
The fix: Apply the filter in FetchXML, not in Liquid
You need to query table B per row using FetchXML with a filter, like:
{% fetchxml queryB %}
<fetch mapping="logical">
<entity name="msdyn_tableb">
<attribute name="msdyn_externalprimarykey" />
<attribute name="msdyn_column1" />
<attribute name="msdyn_column2" />
<filter>
<condition attribute="msdyn_externalprimarykey" operator="eq" value="{{ formattedId }}" />
</filter>
</entity>
</fetch>
{% endfetchxml %}
This forces Dataverse to call the virtual table provider and return the full row, including all attributes.
Important note
This means you will need to run the FetchXML for table B inside the loop for each row in table A.
Yes, it’s more expensive, but it is the only reliable way to retrieve full attribute data from virtual tables in Power Pages.
Summary
-
Liquid filtering does not hydrate virtual table attributes.
-
Virtual table rows only return full data when filtered in FetchXML, not in Liquid.
-
Move the filter into the FetchXML query for table B.
-
Run the FetchXML inside the loop for each ID.