Friday 29 March 2013

Managed VS Un managed Solution in MSCRM 2011

Think of unmanaged solutions as source code and think of managed solutions as compiled, versioned and signed assemblies.
How to delete any of its entities, attributes, relationships, reports and Option Sets from Managed Solution  in MSCRM 2011:


 Hide instead of delete. The easiest solution is to simply create the new attribute with the correct data type and completely hide the old attribute from all views, forms, reports, etc. In many cases, deleting an attribute in production is unacceptable because of data loss so this alternative is the safest and most conservative as you get to keep the old data. The disadvantage is that you will have useless columns in your database and the old attribute will continue to appear in Advanced Find.


2. Use a holding solution to delete any component from your deployed managed solution. This is my favourite approach as it has the advantage of completely deleting from the system the unwanted components without losing any data. This is how it works: Assume you have a solution XXX which contains a custom entity and one of the attributes is of type “Single Line of Text” but you want to change it to “Multiple Lines of Text”. In your target environment you should have solution XXX as managed and in your development environment you should have solution XXX as unmanaged.

  1. In your development environment create a new solution “XXX_holding”. The publisher must be the same as the publisher of your XXX solution.
  2. Add all the components of the XXX solution to your XXX_holding solution*.
  3. Export XXX_holding as managed.
  4. Import XXX_holding to your target environment.
  5. Delete XXX solution from your target environment. No data is lost because all the customizations remain in the holding solution.
  6. In your development environment delete the attribute (you will need to adjust views, forms, etc.).
  7. Export XXX as managed.
  8. Import XXX to your target environment
  9. Delete XXX_holding from your target environment. The attribute will now be deleted from all environments. There is no data loss except for the data that was saved in the old attribute which was deleted.
  10. Now that the attribute is deleted, if you want the attribute back but with a different data type you just need to re-create it in dev and promote the solution to your target environment.
* Note: You can avoid steps 1-3 if you simply open your XXX solution zip file and in the solution.xml file you update the solution unique name to “XXX_holding”. This way you guarantee that you have all the components of XXX also in XXX_holding.


3. Uninstall and re-install solution. If you absolutely need to wipe out the old attribute from the system, you could also uninstall the entire managed solution, make the appropriate changes in your development environment and then re-deploy a clean and correct version of your managed solution. The big disadvantage here is that you will lose your data if it relies on the customizations of your solution, which is usually unacceptable unless you have no data to retain or the data is not important.


4. Use unmanaged solutions instead of managed solutions. While it is true that with unmanaged solutions it is simpler to manually delete any component, it is also true that deploying unmanaged solutions to a production environment has multiple disadvantages and is not a good practice in my perspective. It might also be too late for you to switch to unmanaged solutions.

Tuesday 26 March 2013

MSCRM  Fetch XML 5000 Records Limitation:


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;
}


Friday 22 March 2013

How to Achieve  the creation  of  activity records for each marketing list member  on Addition of marketing list to campaign in MSCRM  2011 Custom workflow:


1. First we have to create a text field ( to have latest marketing list guid which is associated recently ) which should be hidden on campaign  
2.  Update this field on  association of marketing list to campaign (Additem  plugin Message on campaign entity).
3. Write custom work flow on update of this campaign record hidden field   which will fetch the associated marketing list from campaign record based on  hidden field text (which is recently added marketing list guid) , then list members and create custom record for each.



Retrieving Marketing List members  in MSCRM  Statsic VS Dynamic:

Firstly, let’s identify the main difference between a static and dynamic Marketing List. A static Marketing List allows you to use Lookup or Advanced Find to add or remove members from the list. However, this is a manual process.
A dynamic Marketing List allows you to setup parameters to control which records will be added or removed from a list. For example, you can setup your dynamic Marketing List to include all Contacts who live in Auckland. Whenever a new Contact is created and has their City set to “Auckland”, CRM will automatically add them to the Marketing List.
The next important difference to note is the way in which Marketing List members are stored in the CRM database. Like Dynamics CRM 4.0, information regarding members belonging to a static Marketing List is stored in two tables. These are:
List – This table stores information about the Marketing List itself.
List Member – This is an intersect table which links a Contact, Account, or Lead to a particular Marketing List.
 Retrieving Marketing List Members in CRM 2011
For example, if we have a Contact in a static Marketing List, the intersect table will store the ContactId and the ListId to associate both records together.
Let’s contrast this with a dynamic Marketing List which doesn’t use the List or List Member tables at all. Instead, the Listtable stores a field called Query which stores a FetchXML query string to determine the Marketing List members. Carrying on with the example above, we would have a FetchXML representation of “all Contacts who live in Auckland”. When the Marketing List is opened in CRM and a user clicks on Marketing List Members, CRM will run the FetchXML query at runtime and display the results to the user.
 Retrieving Marketing List Members in CRM 2011