Mastering Dataverse Web API Queries for Many-to-Many Relationships
All articles from this blog can ONLY be redistributed on an Attribution-NonCommercial-NoDerivs basis. Please credit the source, thank you.
Twitter:@kelvinshen
Blog:Kelvin Shen's Blog
Navigating Dynamics 365’s Dataverse Web API, especially when dealing with many-to-many relationships, can be a complex endeavor. The intricacies of querying across these relationships present unique challenges that are not immediately evident. This article delves deep into the nuances of this process, highlighting potential pitfalls and demonstrating effective strategies to retrieve the desired data.
Context - The Complex Data Structure
Within our Dynamics 365 Dataverse, we have a designated table for folders intricately linked to contacts through a many-to-many relationship. This multifaceted data structure serves our purpose: determining which contacts have permissions to a given folder, in our case, the ava_accountdocuments
.
Goal
The objective is clear: Efficiently fetch the contacts associated with a specific folder, ava_accountdocuments
, leveraging the power and flexibility of Dataverse WebApi.
Dataverse WebApi Experiment 1: Navigational Mishap
Our maiden query attempt was:
https://baseurl.crm.dynamics.com/api/data/v9.2/ava_ava_accountdocuments_contactSet?$select=ava_accountdocumentsid,ava_ava_accountdocuments_contactid,contactid&$expand=contactid($select=emailaddress1)&$filter=ava_accountdocumentsid eq a4667239-7de0-ea11-a813-000d3a1bb158
The response, however, was less than ideal:
{
"error": {
"code": "0x0",
"message": "Property 'contactid' on type 'Microsoft.Dynamics.CRM.ava_ava_accountdocuments_contact' is not a navigation property or complex property. Only navigation properties can be expanded."
}
}
The root issue? Intersect tables like ava_ava_accountdocuments_contactset
lack navigational properties. Given this, it becomes clear: Direct expansions on such tables aren’t possible, emphasizing the need to navigate using primary entities instead.
Dataverse WebApi Experiment 2: The Extra ‘?’ Conundrum
Post our initial learning, the next query seemed promising:
https://baseurl.crm.dynamics.com/api/data/v9.2/ava_accountdocumentses?$filter=ava_accountdocumentsid%20eq%20a4667239-7de0-ea11-a813-000d3a1bb158&?$expand=ava_ava_accountdocuments_contact($select=contactid,emailaddress1)
But, an unexpected error emerged:
{
"error": {
"code": "0x80060888",
"message": "The query parameter [REDACTED] is not supported"
}
}
The culprit? An errant “?” right before the “$expand” parameter. A simple oversight, but with significant implications. After rectifying, the correct query looks like:
https://baseurl.crm.dynamics.com/api/data/v9.2/ava_accountdocumentses?$filter=ava_accountdocumentsid%20eq%20a4667239-7de0-ea11-a813-000d3a1bb158&$expand=ava_ava_accountdocuments_contact($select=contactid,emailaddress1)&$top=50
Dataverse WebApi Experiment 3: The Single Record Retrieve
Instead of retrieving multiple records, we can precisely fetch a single record and expand its many-to-many relationship. This approach proved fruitful:
https://baseurl.crm.dynamics.com/api/data/v9.2/ava_accountdocumentses(a4667239-7de0-ea11-a813-000d3a1bb158)?$expand=ava_ava_accountdocuments_contact($select=contactid,emailaddress1)
This method serves as an alternative but efficient means to navigate the intricate web of many-to-many relationships in Dynamics 365’s Dataverse.
Conclusion
Querying the Dataverse Web API, especially amidst the maze of many-to-many relationships, is a nuanced craft. It requires understanding, patience, and adaptability. This exploration serves as a testament to the importance of understanding the underlying data structures and the relationships that bind them in Dynamics 365. It also underscores the need for iterative testing and refinement, ensuring data retrieval processes are both effective and efficient.
References
- https://learn.microsoft.com/en-us/power-apps/developer/data-platform/webapi/query-data-web-api#join-tables*