Optimize MS CRM webservice

Currently I'm working on an import program. I have to import thousands and thousands of records. Usually the crm system is quite fast, but with these huge loads, I'm getting quite anoyed by the performance of the MS CRM webservice. It even causes error messages like "The underlying connection was closed: Unable to connect to the remote server.".

Now there are some performance tweaks available. I wanted to write a post about it, but just before I found an article written by Aaron Elder. This is a must-read for people writing code to import bulk data. However, this page has been removed, but the same information is available at Bill's blog: Blog Move: Speed Racer - Call CRM at speeds that would impress even Trixie



Fetch all records

Have you ever tried to write a code which will get you all records from a specific entity? It's harder then you think it is! Everybody who is a bit aware of the CRM SDK thinks it should be a fetch statement like this:

<fetch mapping='logical'><entity name='account'><attribute name='accountid'/></entity>

WRONG!
This would only give you the first 5000 records in the database! It is written down in the SDK with small letters, but it could drive you crazy..

There are two solutions for this issue.
1) Add a registery setting to specify not to implement MaxRowsPerPage
2) Modify the fetch statement and merge several results

Here are the details for each solution
1st solution
Search in the SDK for the word "TurnOffFetchThrottling". You should add this as DWORD registery setting to HKLM\Software\Microsoft\MSCRM. Set the value to 1. You will now not have the 5000 records limit.

2nd solution
Modify your fetch statement to include paging and count numbers. Store all the data in an DataSet and perform that series of code over and over again as long as there is data coming.

Here's the script you should use to get all accountid's (for clarity and the ease of use I have added a function called "FetchDataSet").


private DataSet FetchAllAccountIds(){
int i=1;
bool bFinished = false;
DataSet dsAllData = new DataSet();
while (bFinished == false)
{
StringBuilder sbFetch = new StringBuilder();
sbFetch.AppendFormat("<fetch mapping='logical' page='{0}' count='5000'>", i);
sbFetch.Append("<entity name='account'>");
sbFetch.Append("<attribute name='accountid'/>");
sbFetch.Append("<attribute name='new_12_accountid'/>");
sbFetch.Append("</entity>");
sbFetch.Append("</fetch>");
DataSet dsTempResult = FetchDataSet(sbFetch.ToString());
dsAllData.Merge(dsTempResult);
if (dsTempResult.Tables[0].Rows[0]["morerecords"].ToString() == "0")
{
bFinished = true;
}
else
{
i++;
}
}
return dsAllData;
}

private DataSet FetchDataSet(string fetchXml)
{
string strResult = service.Fetch(fetchXml);
DataSet ds = new DataSet();
System.IO.StringReader reader = new System.IO.StringReader(strResult);
ds.ReadXml(reader);
return ds;
}


I hope this saves you some time!

Thanks to Andrew Krivosheyenko for the Regedit solution!



Save disabled fields

Hi!

I was reading a posting of Ben Vollmer about "Doing Math in Microsoft CRM aka Calculated Field". This is an interesting article, but I noticed something in the posting that I did not know yet. There is a possibility to submit fields which are disabled! I have been using calculated fields before, but I always enabled the field when submitting the page.

So what is the solution? The use of the ForceSubmit attribute.
crmForm.all.field.ForceSubmit = true;

See the SDK for more info



MS CRM Live, open-source client for mobile devices and BizTalk integration

Today at the Worldwide Partner Conference 2006 in Boston, Microsoft has reveiled new information regarding CRM. Take a look at the press release for information regarding the the MS Dynamics CRM Live service, an open-source client for mobile devices and the BizTalk Server-based integration. Press release: http://www.microsoft.com/presspass/press/2006/jul06/07-11CRMLivePR.mspx

I'm looking forward to these products!



New MVP's

The new Dynamics MVP's are announced:

Great Plains
Duke DelPrado
Richard Whaley
Brenner Klenzman

CRM
Ronald Lemmen
Frank Lee

Navision
Ahmed Amini
Alain Krikilion

Solomon
Toni Savage

Let's congratulate them all!!

And yes, I have noticed that my name is in that list as well :) Thanks Matt Parks for nominating!!

Update:
I've added my profile to the mvp website. Click here to find me



Fix alpahabet bar in Dutch CRM

The Dutch version of CRM has a nice bug. The alphabet bar looks like:
A B C D E F G H I K K L M N O P Q R S T U V W x Y Z

As you can see, there are two bugs. The first one is the double K and the second is the lowercase x. This has finally been fixed! They are still working on the kb article pages, but you can request the fix. The KB article is: 919358. In case you can read french or italian, look here: http://support.microsoft.com/kb/919358/fr or http://support.microsoft.com/kb/919358/it. The other languages will come slowly, but thats not that important. Just request the fix :)



Modifying the fullname

The fullname of a contact is always "firstname lastname". Right? Well, did you know that you can modify this? Go to Settings, System Settings. There you can modify this setting to some other options!

Great :) So lets modify the fullname to "lastname, firstname". When saving this setting, CRM warns you that this only works for the new entities and not for the existing entities. If this really is a problem, then you can go into SQL and update the fullname manually. Here's the code to update the contacttable:

UPDATE contactbase SET fullname = ISNULL(lastname, '') + ', ' + ISNULL(firstname, '')

Of course you can update the contactbase with other values for the fullname as well.

Keep in mind that you NEVER update the Contact view, always the contactbase. Updating the contact view will cause problems.

Anyway, you should always make a backup of your database before making any modification to the database.