While communicating with CRM Entities using Retrieve Multiple operation using request response pattern there are some scenarios where you need to process bulk request queries like using pattern matching Contains Data, Not null, etc.
These query results bulk data to BizTalk as a response in XML Format with all the details.
Scenario 1: Assume you need to process 10,000 records by interacting with CRM.
OR
Scenario 2: Single fetch Query, Expression can get you up to 5,000 records.
Handling these huge file in BizTalk at once could result in performance impact. Now think of scenario when you have to process multiples request of such huge records. 5000 records XML data can be up to 500 MB plus, depending on the data you retrieve like column / attributes.
Fig – Retrieve Operation
The below request will return you all the column for the GUID matching record.
<Retrieve xmlns="http://schemas.microsoft.com/xrm/2011/Contracts/Services">
<entityName>account</entityName>
<id>1D30CA6E-E355-E511-80F2-C4346BC5A780</id>
<columnSet xmlns:b="http://schemas.microsoft.com/xrm/2011/Contracts" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<b:AllColumns>true</b:AllColumns>
<b:Columns xmlns:c="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<c:string>name</c:string>
</b:Columns>
</columnSet>
</Retrieve>
Sample XML Retrieve Request
Fig – Retrieve Multiple Operation
Sample Retrieve Multiple Request from BizTalk to CRM in two formats FetchExpression, QueryExpression for the same query.
The below sample basic query will return all the entity records with all the columns / attributes specified, maximum entity records can be 5000 as it’s a limit at CRM.
<RetrieveMultiple xmlns="http://schemas.microsoft.com/xrm/2011/Contracts/Services" xmlns:ns2="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:ns0="http://schemas.microsoft.com/xrm/2011/Contracts/Services" xmlns:ns3="http://schemas.microsoft.com/xrm/2011/Metadata" xmlns:ns5="http://schemas.microsoft.com/2003/10/Serialization/" xmlns:ns1="http://schemas.datacontract.org/2004/07/System.Collections.Generic" xmlns:ns4="http://schemas.microsoft.com/xrm/2011/Contracts">
<query i:type="b:FetchExpression" xmlns:b="http://schemas.microsoft.com/xrm/2011/Contracts" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<b:Query>
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false" >
<entity name="sms_registrationpage">
<attribute name="sms_registrationpageid" />
<attribute name="sms_firstname" />
<attribute name="sms_mobile" />
<attribute name="sms_lastname" />
<attribute name="sms_ismarried" />
<attribute name="sms_gender" />
<attribute name="sms_emailid" />
<attribute name="sms_country" />
<attribute name="sms_age" />
<order attribute="sms_firstname" descending="false" />
</entity>
</fetch>
</b:Query>
</query>
</RetrieveMultiple>
Fig- Retrieve Multiple Using FetchExpression
<RetrieveMultiple xmlns="http://schemas.microsoft.com/xrm/2011/Contracts/Services" xmlns:ns2="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:ns0="http://schemas.microsoft.com/xrm/2011/Contracts/Services" xmlns:ns3="http://schemas.microsoft.com/xrm/2011/Metadata" xmlns:ns5="http://schemas.microsoft.com/2003/10/Serialization/" xmlns:ns1="http://schemas.datacontract.org/2004/07/System.Collections.Generic" xmlns:ns4="http://schemas.microsoft.com/xrm/2011/Contracts">
<query i:type="b:QueryExpression" xmlns:b="http://schemas.microsoft.com/xrm/2011/Contracts" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<b:ColumnSet>
<b:AllColumns>false</b:AllColumns>
<b:Columns xmlns:e="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<e:string>sms_registrationpageid</e:string>
<e:string>sms_firstname</e:string>
<e:string>sms_mobile</e:string>
<e:string>sms_lastname</e:string>
<e:string>sms_ismarried</e:string>
<e:string>sms_gender</e:string>
<e:string>sms_emailid</e:string>
<e:string>sms_country</e:string>
<e:string>sms_age</e:string>
</b:Columns>
</b:ColumnSet>
<b:Criteria>
<b:Conditions/>
<b:FilterOperator>And</b:FilterOperator>
<b:Filters/>
</b:Criteria>
<b:Distinct>false</b:Distinct>
<b:EntityName>sms_registrationpage</b:EntityName>
<b:LinkEntities/>
<b:Orders>
<b:OrderExpression>
<b:AttributeName>sms_firstname</b:AttributeName>
<b:OrderType>Ascending</b:OrderType>
</b:OrderExpression>
</b:Orders>
<b:PageInfo>
<b:Count>0</b:Count>
<b:PageNumber>1</b:PageNumber>
<b:PagingCookie i:nil="true"/>
<b:ReturnTotalRecordCount>false</b:ReturnTotalRecordCount>
</b:PageInfo>
<b:NoLock>false</b:NoLock>
</query>
</RetrieveMultiple>
Fig- Retrieve Multiple Request Using QueryExpression
There can be some scenario where you need to query the CRM records and process the response data records in set of records. You can use the paging cookie feature to make paging in an application faster for large datasets. When you use the paging cookie feature when querying a set of records, the result contains a value for the paging cookie. To improve system performance, you can then pass that value when you retrieve the next set of records.
Assume that an entity has 10,000 records and BizTalk has to query to get those records and process individual records within a loop. Here we know that CRM will return maximum of 5000 records in single response. In this case we can split it up with two requests, set 1st to get 1st 5000, 2nd set to get next another 5000 records and then process them in BizTalk. The downside here will be that file with 5000 records will be size approx 300 – 500 MB depending on the attributes selections.
Assume, an entity has 10,000 records, BizTalk has to process them individually. Here the requirement is to query a set of 1000 records at a time, process them in BizTalk and then go for next set of batch of records and so on. So BizTalk has to query CRM 10 times to get 1000 records every time to process 10,000 records. Going with this approach there will be less load in BizTalk as we restricted the batch size.
The approach discussed in Scenario 2 is more performance oriented and yield better results.
Fig – CRM Entity Records total 4 records.
Fig – Mapping to FetchExpression
<xsl:template name="FetchExpression">
<xsl:param name="Count" />
<xsl:param name="pageIndex"/>
<xsl:param name="pageCookie" />
<RetrieveMultiple xmlns="http://schemas.microsoft.com/xrm/2011/Contracts/Services">
<query i:type="b:FetchExpression" xmlns:b="http://schemas.microsoft.com/xrm/2011/Contracts" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<b:Query>
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false" count="<xsl:value-of select="$Count"/>" <xsl:if test="$pageIndex">
page="<xsl:value-of select="$pageIndex"/>"
</xsl:if> <xsl:if test="$pageCookie">
paging-cookie="<xsl:value-of select="$pageCookie"/>"
</xsl:if> >
<entity name="sms_registrationpage">
<attribute name="sms_registrationpageid" />
<attribute name="sms_firstname" />
<attribute name="sms_mobile" />
<attribute name="sms_lastname" />
<attribute name="sms_ismarried" />
<attribute name="sms_gender" />
<attribute name="sms_emailid" />
<attribute name="sms_country" />
<attribute name="sms_age" />
<order attribute="sms_firstname" descending="false" />
</entity>
</fetch>
</b:Query>
</query>
</RetrieveMultiple
</xsl:template>
Fig – XSLT Used in Scripting
Fig – End to End Output FetchExpression Request, Response with Count Set to 2
Fig – Mapping to QueryExpression Request, Response with Count Set to 2
<xsl:template name="QueryExpression">
<xsl:param name="Count" />
<xsl:param name="pageIndex"/>
<xsl:param name="pageCookie" />
<RetrieveMultiple xmlns="http://schemas.microsoft.com/xrm/2011/Contracts/Services">
<query i:type="b:QueryExpression" xmlns:b="http://schemas.microsoft.com/xrm/2011/Contracts" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<b:ColumnSet>
<b:AllColumns>false</b:AllColumns>
<b:Columns xmlns:e="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<e:string>sms_registrationpageid</e:string>
<e:string>sms_firstname</e:string>
<e:string>sms_mobile</e:string>
<e:string>sms_lastname</e:string>
<e:string>sms_ismarried</e:string>
<e:string>sms_gender</e:string>
<e:string>sms_emailid</e:string>
<e:string>sms_country</e:string>
<e:string>sms_age</e:string>
</b:Columns>
</b:ColumnSet>
<b:Criteria>
<b:Conditions/>
<b:FilterOperator>And</b:FilterOperator>
<b:Filters/>
</b:Criteria>
<b:Distinct>false</b:Distinct>
<b:EntityName>sms_registrationpage</b:EntityName>
<b:LinkEntities/>
<b:Orders>
<b:OrderExpression>
<b:AttributeName>sms_firstname</b:AttributeName>
<b:OrderType>Ascending</b:OrderType>
</b:OrderExpression>
</b:Orders>
<b:PageInfo>
<xsl:choose>
<xsl:when test="$Count">
<b:Count>
<xsl:value-of select="$Count"/>
</b:Count>
</xsl:when>
<xsl:otherwise>
<b:Count>0</b:Count>
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test="$pageIndex">
<b:PageNumber>
<xsl:value-of select="$pageIndex"/>
</b:PageNumber>
</xsl:when>
<xsl:otherwise>
<b:PageNumber>0</b:PageNumber>
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test="$pageCookie">
<b:PagingCookie>
<xsl:value-of select="$pageCookie"/>
</b:PagingCookie>
</xsl:when>
<xsl:otherwise>
<b:PagingCookie i:nil="true"/>
</xsl:otherwise>
</xsl:choose>
<b:ReturnTotalRecordCount>false</b:ReturnTotalRecordCount>
</b:PageInfo>
<b:NoLock>false</b:NoLock>
</query>
</RetrieveMultiple>
</xsl:template>
Fig – XSLT Used in Scripting
Fig – End to End Output QueryExpression Request, Response with Count Set to 2
Another important place to find a huge amount of BizTalk related articles is the TechNet Wiki itself. The best entry point is BizTalk Server Resources on the TechNet Wiki