Can you write a single FetchXML query to get 1:many relationship? - dynamics-crm

Is it possible to write a single FetchXML query that gets a root entity and multiple children? All I've been able to do is 1:1.

James Wood is correct. Fetch XML is recursive so by using the link entity you can get the information you want.
For example, the following is valid:
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="true">
<entity name="account">
<attribute name="name" />
<attribute name="primarycontactid" />
<attribute name="telephone1" />
<attribute name="accountid" />
<order attribute="name" descending="false" />
<link-entity name="contact" from="parentcustomerid" to="accountid" alias="aj">
<attribute name="firstname" />
<attribute name="lastname" />
<attribute name="telephone1" />
<link-entity name="businessunit" from="businessunitid" to="owningbusinessunit" alias="ak">
<attribute name="name" />
<attribute name="address1_line1" />
<attribute name="address1_line2" />
<attribute name="address1_line3" />
<filter type="and">
<condition attribute="name" operator="not-null" />
</filter>
</link-entity>
</link-entity>
</entity>
</fetch>
If your question really is "Is it possible to write a single FetchXML query that gets a SINGLE root entity and multiple children" then the answer is unfortunately no. However if you are able to handle duplicates of root data (For example using the Grouping functionality of an SSRS report) then what you require is entirely possible

Unless I've misunderstood the question this is very possible.
So for example you want to find all the contacts related to a given account. This is represented in Crm by the Parent Customer Lookup on the contact to the account.
<fetch mapping="logical" count="100" version="1.0">
<entity name="account">
<attribute name="name" />
<link-entity name="contact" from="parentcustomerid" to="accountid">
<attribute name="fullname" />
</link-entity>
</entity>
</fetch>
Which gives you a result set that looks like this:
<resultset morerecords="0" paging-cookie="<cookie page="1"><accountid last="{E704FAD6-2D4B-E111-9FED-00155D828444}" first="{AD912122-6B3C-E111-9B37-00155D828444}" /></cookie>">
<result>
<name>RGD Mining Inc</name>
<accountid>{E704FAD6-2D4B-E111-9FED-00155D828444}</accountid>
<accountid.fullname>Bill Miner</accountid.fullname>
</result>
<result>
<name>RGD Mining Inc</name>
<accountid>{E704FAD6-2D4B-E111-9FED-00155D828444}</accountid>
<accountid.fullname>Green</accountid.fullname>
</result>
</resultset>

No, it is not possible.

I'm happy to report that it is possible. I have a solution that worked well for me.
The only caveat is that if you have multiple child accounts you will get multiple results for the parent. For example:
parent 1: child 1
parent 2: child 1
parent 2: child 2
This means that you would then have to run the results through a sorting function, to get either all the children under parents in a multi dimensional array, or get all the accounts as unique entries in a flat array.
Also, this only goes down one level. If your hierarchy is multi-level, this code would need to be modified.
<fetch distinct="false" mapping="logical">
<entity name="account">
<attribute name="name" />
<link-entity name="account" alias="childaccount" to="accountid" from="parentaccountid" link-type="outer">
<attribute name="name" alias="childname" />
</link-entity>
</entity>
</fetch>

Related

Filter users by type Dynamics 365

I am trying to exclude App Users from a view in Dynamics 365 CRM. The fetch xml is very simple:
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<entity name="systemuser">
<attribute name="fullname" />
<attribute name="businessunitid" />
<attribute name="title" />
<attribute name="address1_telephone1" />
<attribute name="positionid" />
<attribute name="systemuserid" />
<order attribute="fullname" descending="false" />
<filter type="and">
<condition attribute="type" operator="ne" value="App User" />
</filter>
</entity>
</fetch>
I need to place a filter in my query like this seudo code: <condition attribute="type" operator="ne" value="App User" />, sort of a field that allows me to filter by user type. Is there any field that could deterministically say that a user is an app user?
Typically, Non-interactive App user will be created with the attribute Access mode = 4 in system user entity. So this should work.
<condition attribute="accessmode" operator="ne" value="4" />

How to pass null or empty to FetchXML filters?

Scenario: I've a text field in Dynamics CRM on Order Type. This field is integrated with some other systems and it'll be accepting only already stated list of values; like, ABC, IJK, XYZ etc. Now I can query this field using Advanced find if it contain data or not.
Now in report, I've a parameter that is having all those possible value and one additional as "Does not contain data" and its value is empty string. I've also enabled this report parameter for multi-select. But I am unable to get the orders if any of the value is selected from report parameters.
Below is my FetchXML query, Please let me know what I am missing in below.
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<entity name="invoicedetail">
<attribute name="productid" />
<attribute name="invoicedetailid" />
<attribute name="tv_ordertype" />
<order attribute="productid" descending="false" />
<filter type="and">
<condition attribute="tv_ordertype" operator="in" value="#Order_Types" />
</filter>
</entity>
</fetch>
Unfortunately you cannot combine the values ("ABC", "IJK", "XYZ") with an empty string option. Think about how SSRS will parse the empty string into FetchXml:
<condition attribute="tv_ordertype" operator="in" value="" />
Because the in operator has an empty string, there will be no matching results.
One approach that might work is to change your FetchXml to use an or filter, like this
<filter type="or">
<condition attribute="tv_ordertype" operator="null" />
<condition attribute="tv_ordertype" operator="in" value="#Order_Types" />
</filter>
This will now return all values from CRM that match your criteria OR have a null tv_ordertype
Then you can apply additional filtering at the tablix / report level
Try something like below
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<entity name="invoicedetail">
<attribute name="productid" />
<attribute name="invoicedetailid" />
<attribute name="tv_ordertype" />
<order attribute="productid" descending="false" />
<filter type='and'>
<condition attribute="tv_ordertype" operator="in" value="#Order_Types" />
</filter>
</entity>
</fetch>
Your fetch XML should look like this:
<?xml version="1.0" encoding="UTF-8"?>
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<entity name="invoicedetail">
<attribute name="productid" />
<attribute name="invoicedetailid" />
<attribute name="tv_ordertype" />
<order attribute="productid" descending="false" />
<filter type="and">
<condition attribute="tv_ordertype" operator="in"/>
<value>#Order_Types[0]</value>
<value>#Order_Types[1]</value>
<!-- etc -->
</condition>
</filter>
</entity>
</fetch>

Dynamics - How to get all appointments that for a specific user attends by Web Api

In Dynamics CRM, I'm trying to get all the appointments where a specific user is an attendee, using Web API. I know that I have to deal with Appointment entity and ActivityParty with activitypartytypemask equals 9 but really cannot figure out how to make it. How can identify the attendee ?
You can use FetchXml for your purpose. Check following Fetch:
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="true">
<entity name="appointment">
<attribute name="subject" />
<attribute name="statecode" />
<attribute name="scheduledstart" />
<attribute name="scheduledend" />
<attribute name="regardingobjectid" />
<attribute name="activityid" />
<link-entity name="activityparty" from="activityid" to="activityid" alias="aa">
<filter type="and">
<condition attribute="participationtypemask" operator="in">
<value>6</value>
<value>5</value>
</condition>
<condition attribute="partyid" operator="eq" value="{9CE2BF21-408B-E611-80F3-C4346BAC7ABC}" />
</filter>
</link-entity>
</entity>
</fetch>
Using provided FetchXml and WebApi you should get the result you wanted. Url should look like following:
[Server Base Url]/api/data/v8.2/appointments?fetchXml=%3Cfetch%20version%3D%221.0%22%20output-format%3D%22xml-platform%22%20mapping%3D%22logical%22%20distinct%3D%22true%22%3E%3Centity%20name%3D%22appointment%22%3E%3Cattribute%20name%3D%22subject%22%20%2F%3E%3Cattribute%20name%3D%22statecode%22%20%2F%3E%3Cattribute%20name%3D%22scheduledstart%22%20%2F%3E%3Cattribute%20name%3D%22scheduledend%22%20%2F%3E%3Cattribute%20name%3D%22regardingobjectid%22%20%2F%3E%3Cattribute%20name%3D%22activityid%22%20%2F%3E%3Clink-entity%20name%3D%22activityparty%22%20from%3D%22activityid%22%20to%3D%22activityid%22%20alias%3D%22aa%22%3E%3Cfilter%20type%3D%22and%22%3E%3Ccondition%20attribute%3D%22participationtypemask%22%20operator%3D%22in%22%3E%3Cvalue%3E6%3C%2Fvalue%3E%3Cvalue%3E5%3C%2Fvalue%3E%3C%2Fcondition%3E%3Ccondition%20attribute%3D%22partyid%22%20operator%3D%22eq%22%20value%3D%22%7B9CE2BF21-408B-E611-80F3-C4346BAC7ABC%7D%22%20%2F%3E%3C%2Ffilter%3E%3C%2Flink-entity%3E%3C%2Fentity%3E%3C%2Ffetch%3E
This article contains additional details.

Request URL Too Long for fetchXml query types

I'm using CRM 2016 web api with fetchxml query parameter, but my query is too long it's simulate the IN operator were the number of parameters passed in the IN list are 300 elements and some times will be more than that.
So my problem is the query are too big for a GET HTTP Request. I have tried to send the query in the http message body but that didn't work so what is the solution for this problem?
Here's a code snippet of the fetchxml query that I used:
<fetch mapping="logical" distinct="true">
<entity name="entity">
<attribute name="new_classopportunityid" />
<attribute name="new_trainingproduct" />
<attribute name="new_gtgstatus" />
<attribute name="new_scheduledstartdate" />
<attribute name="new_scheduledenddate" />
<attribute name="new_remainingnumberofseats" />
<attribute name="new_liveclassroom" />
<attribute name="new_maxlive" />
<attribute name="new_xavieruniversity" />
<attribute name="new_partnerlive" />
<attribute name="new_blended" />
<filter>
<condition attribute="new_classopportunityid" operator="in">
<value>001943ea-e263-e611-8158-00155d002810</value>
<value>0071e4ea-bd9b-e611-8163-00155d002810</value>
<value>00c32774-1c8f-e611-8161-00155d002810</value>
<value>00d513fa-f0bb-e611-8169-00155d002810</value>
<value>....</value>
<value>....</value>
<value>....</value>
</condition>
</filter>
</entity>
</fetch>
The CRM web api endpoint that I request is :
GET http://<org>/api/data/v8.0/<entity>?fetchXml=<fetch mapping="logical" distinct="true">
<entity name="entity">
<attribute name="new_classopportunityid" />
<attribute name="new_trainingproduct" />
<attribute name="new_gtgstatus" />
<attribute name="new_scheduledstartdate" />
<attribute name="new_scheduledenddate" />
<attribute name="new_remainingnumberofseats" />
<attribute name="new_liveclassroom" />
<attribute name="new_maxlive" />
<attribute name="new_xavieruniversity" />
<attribute name="new_partnerlive" />
<attribute name="new_blended" />
<filter>
<condition attribute="new_classopportunityid" operator="in">
<value>001943ea-e263-e611-8158-00155d002810</value>
<value>0071e4ea-bd9b-e611-8163-00155d002810</value>
<value>00c32774-1c8f-e611-8161-00155d002810</value>
<value>00d513fa-f0bb-e611-8169-00155d002810</value>
<value>....</value>
<value>....</value>
<value>....</value>
</condition>
</filter>
</entity>
</fetch>
This is the response I got from the api.
Error code: 414: HTTP/1.1 414 Request-URI Too Long Response : "<!DOCTYPE HTML PUBLIC \"-\/\/W3C\/\/DTD HTML 4.01\/\/EN\"\"http:\/\/www.w3.org\/TR\/html4\/strict.dtd\">\r\n<HTML><HEAD><TITLE>Request URL Too Long<\/TITLE>\r\n<META HTTP-EQUIV=\"Content-Type\" Content=\"text\/html; charset=us-ascii\"><\/HEAD>\r\n<BODY><h2>Request URL Too Long<\/h2>\r\n<hr><p>HTTP Error 414. The request URL is too long.<\/p>\r\n<\/BODY><\/HTML>\r\n" [] []
You'll need to use a Post, not a Get:
https://dreamingincrm.com/2017/01/15/executing-large-fetchxml-with-webapi/
Using the "in" operator with a big list of ids is probably not the best way to query, as you've seen. It would be better if you could filter on an attribute of the new_classopportunity entity by using a link-entity, like this:
<fetch mapping="logical" distinct="true" >
<entity name="entity" >
<!-- ... all your attributes ... -->
<link-entity name="new_classopportunity" from="new_classopportunityid" to="new_classopportunityid" >
<attribute name="new_name" />
<filter>
<condition attribute="statecode" operator="eq" value="0" />
</filter>
</link-entity>
</entity>
</fetch>
Notice you can pull in attributes from the link-entity as well. In this case I'm pulling in name and using a filter to only get new_classopportunity records that are active.
If you don't have a field on new_classopportunity that you can filter on to get the same list, add one! :)

View Showing Accounts that don't have contact

I want to create two views.
- One view showing all accounts having contacts. It is easy. I don't have any issue with this.
- Second View Showing All Accounts don't have any contact.
As we can't specify such condition for second view in advance find. Is there any way we can achieve this using Views?
I don't want to create SSRS report or any custom Development.
Please let me know if this is achievable.
You can achieve this only by modifying the Account entity customization xml.
Create a new (system) view for Account and name it "Active Accounts without Contacts".
Create a (unmanaged) solution for export and add the Account entity without any dependencies.
Export the solution and unpack the zip archive.
Open the customization.xml with the editor of your choice.
Modify the views FetchXml as follows:
before
...
<fetchxml>
<fetch version="1.0" output-format="xml-platform" mapping="logical">
<entity name="account">
<attribute name="accountid" />
<order attribute="name" descending="false" />
</entity>
</fetch>
</fetchxml>
<IntroducedVersion>1.0.0.0</IntroducedVersion>
<LocalizedNames>
<LocalizedName description="Active Accounts without Contacts" languagecode="1033" />
</LocalizedNames>
<Descriptions>
<Description description="Active Accounts without Contacts" languagecode="1033" />
</Descriptions>
...
after
<fetchxml>
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="true">
<entity name="account">
<attribute name="accountid" />
<order attribute="name" descending="false" />
<link-entity name="contact" from="parentcustomerid" to="accountid" link-type="outer"/>
<filter type="and">
<condition attribute="parentcustomerid" operator="null" />
</filter>
</entity>
</fetch>
</fetchxml>
<IntroducedVersion>1.0.0.0</IntroducedVersion>
<LocalizedNames>
<LocalizedName description="Active Accounts without Contacts" languagecode="1033" />
</LocalizedNames>
<Descriptions>
<Description description="Active Accounts without Contacts" languagecode="1033" />
</Descriptions>
...
Finally, re-package the solution, import and publish.
I could not get this to work, and after quite a bit of "tinkering" altered the fetchxml as follows and it works! I basically moved the filter to before the link-entity detail. This is on CRM2013 with Rollup 1.
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="true" >
<entity name="account" >
<attribute name="address1_city" />
<filter type="and" >
<condition entityname="contact" attribute="parentcustomerid" operator="null" />
</filter>
<link-entity name="contact" from="parentcustomerid" to="accountid" link-type="outer" />
<attribute name="primarycontactid" />
<order attribute="name" descending="false" />
<attribute name="telephone1" />
<attribute name="accountid" />
</entity>
</fetch>

Resources