I have created a XRMTool(WPF) to extract data from Dynamics CRM Online to XML file. The output file could probably have a million rows, but I am getting the following error.
Failed to allocate a managed memory buffer of 2147483647 bytes. The amount of available memory may be low.
I can add some filters and reduce the number of rows but as per the application requirement, I have to extract at least a months data in a single go, which will be around a million rows.
How can I increase the memory buffer in WPF application?
Following is my code
string fetchaudit = @"<fetch version='1.0' mapping='logical' output-format='xml-platform'>
<entity name='audit'>
<attribute name='action' />
<attribute name='auditid' />
<attribute name='callinguserid' />
<attribute name='objecttypecode' />
<attribute name='createdon' />
<attribute name='objectid' />
<attribute name='objectid' />
<attribute name='operation' />
<attribute name='regardingobjectid' />
<attribute name='transactionid' />
<attribute name='userid' />
<filter type='and'>
<condition attribute='createdon' operator='on-or-after' value='" + Fromdate + @"' />
<condition attribute='createdon' operator='on-or-before' value='" + Todate + @"' />
</filter>
</entity>
</fetch>";
while (true)
{
string xml = CreateXml(fetchaudit, pagingCookie, pageNumber, fetchCount);
RetrieveMultipleRequest fetchRequest1 = new RetrieveMultipleRequest
{
Query = new FetchExpression(xml) // Error occurs here when page number reaches 100
};
EntityCollection returnCollection = ((RetrieveMultipleResponse)_ctrl.CrmConnectionMgr.CrmSvc.Execute(fetchRequest1)).EntityCollection;
// var collection = _ctrl.CrmConnectionMgr.CrmSvc.GetEntityDataByFetchSearchEC(xml);
if (returnCollection != null)
{
if (returnCollection.Entities.Count >= 0)
Entities.AddRange(returnCollection.Entities);
}
if (returnCollection.MoreRecords)
{
pageNumber++;
pagingCookie = returnCollection.PagingCookie;
}
else
{
break;
}
} // end while
I am using the following approach from SDK for paging SampleCode\CS\GeneralProgramming\Queries\FetchPagingWithCookie.cs (https://msdn.microsoft.com/en-us/library/gg309717.aspx)
Most probably the exception is not happening on the first request, if so, than reduce amount of returned rows.
Your current problem is that you are storing everything in memory till the end of retrieving
The collection of
Entities
is growing rapidly, but it's not failed on adding because memory allocation happening on actual SDK retrieve.To Serialize a results of query as a single collection with
DataContractSerializer
you can use next IEnumerable implementation to read data by packs (and more clarifications for the code):it uses
QueryExpression
and notFetchXml
, but you can easily convert itusage sample:
Additionaly you can create a child class of
XrmEnumerable
and do your logic inAdd
function