Recently I was asked by a client for Dynamics CRM Functional Design Document. After several internal and external meetings here is the template we have come up with. Please note this is not a complete list. This is meant to be a starting guide for anyone trying to use this document. Feel free to add your company's specific details.
Feel free to comment on the blog to get the conversation going.
Microsoft Dynamics CRM
Tuesday 29 August 2017
Thursday 10 March 2016
Coding Standards for Dynamics CRM
Recently I was asked by a partner for Dynamics CRM coding standards. There is a lot of coding standards for .Net and JavaScript projects. However I could not find any specific coding standards for Dynamics CRM.
After few days of attempt, I have documented coding standards for Dynamics CRM here. Please note this is not a complete list. This is meant to be a starting guide for anyone trying to use this document. Feel free to add your company's specific standards.
Feel free to comment on the blog to get the conversation going.
After few days of attempt, I have documented coding standards for Dynamics CRM here. Please note this is not a complete list. This is meant to be a starting guide for anyone trying to use this document. Feel free to add your company's specific standards.
Feel free to comment on the blog to get the conversation going.
Sunday 9 August 2015
Optimistic Concurrency in Dynamics CRM
When more than one user selects the same record and tries to save the record with different updates at the same time, one of the users will have a data loss. To avoid this, you can enable optimistic concurrency when saving and updating the records.
So the main difference is ability to check the version of the transaction and update only if the version number matches.Optimistic concurrency is supported on all out-of-box entities enabled for offline sync and all custom entities. For OOTB entities check if the attribute IsOptimisticConcurrencyEnabled is set to true. For custom entities, this property is set to true by default.
Please note for Microsoft Dynamics CRM Online organizations, this feature is available only if your organization has updated to Dynamics CRM Online 2015 Update 1. This feature is not available for Dynamics CRM on-premise.
Here is the code samples:
Update if version number matches:
if (account != null && account["address1_postalcode"] != null && account["address1_postalcode"] == "90210")
{
Entity updatedAccount = new Entity(){
LogicalName = account.LogicalName,
Id = account.Id,
RowVersion = account.RowVersion
};
Target = updatedAccount, ConcurrencyBehavior = ConcurrencyBehavior.IfVersionMatches
};
UpdateResponse accountUpdateResponse = service.Execute<UpdateResponse>(accountUpdate);
}
Delete if version number matches:
EntityReference accountToDelete = new EntityReference()
{
LogicalName = account.LogicalName,
};
DeleteRequest accountDelete = new DeleteRequest()
{
Target = accountToDelete,
ConcurrencyBehavior = ConcurrencyBehavior.IfVersionMatches
};
DeleteResponse accountDeleteResponse = service.Execute<DeleteResponse>(accountDelete);
}
catch (FaultException<OrganizationServiceFault> ex)
{
if (ex.Code == OPTIMISTIC_CONCURRENCY_VIOLATION) {…}
}
So the main difference is ability to check the version of the transaction and update only if the version number matches.Optimistic concurrency is supported on all out-of-box entities enabled for offline sync and all custom entities. For OOTB entities check if the attribute IsOptimisticConcurrencyEnabled is set to true. For custom entities, this property is set to true by default.
Please note for Microsoft Dynamics CRM Online organizations, this feature is available only if your organization has updated to Dynamics CRM Online 2015 Update 1. This feature is not available for Dynamics CRM on-premise.
Here is the code samples:
Update if version number matches:
var
account = service.Retrieve("account",accountId,
new ColumnSet("name","address1_postalcode","creditlimit"));
if (account != null && account["address1_postalcode"] != null && account["address1_postalcode"] == "90210")
{
Entity updatedAccount = new Entity(){
LogicalName = account.LogicalName,
Id = account.Id,
RowVersion = account.RowVersion
};
updatedAccount["creditlimit"]
= 1000000;
UpdateRequest
accountUpdate
= new UpdateRequest(){
Target = updatedAccount, ConcurrencyBehavior = ConcurrencyBehavior.IfVersionMatches
};
UpdateResponse accountUpdateResponse = service.Execute<UpdateResponse>(accountUpdate);
}
Delete if version number matches:
EntityReference accountToDelete = new EntityReference()
{
LogicalName = account.LogicalName,
Id = account.Id,
RowVersion = account.RowVersion};
DeleteRequest accountDelete = new DeleteRequest()
{
Target = accountToDelete,
ConcurrencyBehavior = ConcurrencyBehavior.IfVersionMatches
};
try
{DeleteResponse accountDeleteResponse = service.Execute<DeleteResponse>(accountDelete);
}
catch (FaultException<OrganizationServiceFault> ex)
{
if (ex.Code == OPTIMISTIC_CONCURRENCY_VIOLATION) {…}
}
Wednesday 5 August 2015
Multiple Rollups and service pack on same server
Have you ever wished if you can have multiple rollup on the same server? Thanks to Rafael Urbano for this trick.
Here is the steps for this:
1) Disable the organisation that you do not want to upgrade.
2) Apply the roll up / service pack to rest of the organisation.
3) Enable the organisation that you do not want to upgrade. At this time, system will ask that there are new rollups available, do you want to upgrade. Select No for this.
There you go. You have same server and multiple organisations on different roll ups. This is what deployment administrator console shows.
Here is the steps for this:
1) Disable the organisation that you do not want to upgrade.
2) Apply the roll up / service pack to rest of the organisation.
3) Enable the organisation that you do not want to upgrade. At this time, system will ask that there are new rollups available, do you want to upgrade. Select No for this.
There you go. You have same server and multiple organisations on different roll ups. This is what deployment administrator console shows.
Hope this helps
Monday 22 June 2015
Duplicate Appointments in Outlook 2013
Recently I was working on a project where service appointment and recurring appointment in client's outlook 2013 client kept duplicating itself when the appointment is tracked / created in CRM. This is what resolved the issue for us:
1: The presence of the HKEY_CLASSES_ROOT\TypeLib\{2DF8D04C-5BFA-101B-BDE5-00AA0044DE52} registry key.
Followed
these steps:
2: Previous
version of Office had left behind reference to an older OLB file.
3: Removed third party add-ins
Resolution:
1: The presence of the HKEY_CLASSES_ROOT\TypeLib\{2DF8D04C-5BFA-101B-BDE5-00AA0044DE52} registry key.
1. Exit Outlook.
2. Click Start, click Run, type regedit,
and then click OK.
3. Locate the following registry subkey:
HKEY_CLASSES_ROOT\TypeLib\{2DF8D04C-5BFA-101B-BDE5-00AA0044DE52}
4. Right-click on the registry key, and then
select Export. Save the export to your desktop to create a backup.
5. Right-click on the key again, and then select delete.
6. Start Outlook.
Followed
these steps:
1. Exit Outlook.
2. Click Start, click Run, type regedit, and then click OK.
3. Locate the following registry subkey:
4. HKEY_CLASSES_ROOT\TypeLib\{00062FFF-0000-0000-C000-000000000046}
5. Delete the version keys (e.g. 9.4 and 9.3) for any version of Outlook that is not installed on your system based on the version table provided below. For example, if you are not using Outlook 2013 then remove the "9.5" entry. If you are not using Outlook 2010 then remove the "9.4" entry. If you are not using Outlook 2007 then remove the "9.3" entry.
Outlook
|
Version
|
Outlook 2003
|
9.2
|
Outlook 2007
|
9.3
|
Outlook 2010
|
9.4
|
Outlook 2013
|
9.5
|
3: Removed third party add-ins
o Business Connectivity Services Add-ins
o McAfee E-mail Scan Add-ins
4: Upgrade CRM
client for outlook from Service Pack 1 to Service Pack 1-UR1 for CRM 2013
Note: Please backup the registry before making any changes. Also please make registry changes at your own risk.
Tuesday 16 June 2015
Async maintenance job schedule
When we deploy CRM and are in a rush to go Live, we often forget to check for time the asynchronous maintenance job executes.
The Dynamics CRM platform's asynchronous jobs are automatically scheduled to run at a default frequency scheduled at the random start time when CRM organisation is created. By default CRM will create six maintenance jobs which are scheduled to run daily. These jobs are executed by the Microsoft Dynamics CRM Asynchronous Processing Service (maintenance).
◾Deletion Service
◾Indexing Management
◾Reindex All
◾Clean up Workflows
◾Create Audit Partition
◾Check For MUI Updates
This means that the maintenance job might execute at the peak system usage time. To avoid having performance issues it is suggested to schedule this job to run after hours.
You can use the tool available on codeplex to reschedule the jobs after hours.
Hope this helps.
The Dynamics CRM platform's asynchronous jobs are automatically scheduled to run at a default frequency scheduled at the random start time when CRM organisation is created. By default CRM will create six maintenance jobs which are scheduled to run daily. These jobs are executed by the Microsoft Dynamics CRM Asynchronous Processing Service (maintenance).
◾Deletion Service
◾Indexing Management
◾Reindex All
◾Clean up Workflows
◾Create Audit Partition
◾Check For MUI Updates
This means that the maintenance job might execute at the peak system usage time. To avoid having performance issues it is suggested to schedule this job to run after hours.
You can use the tool available on codeplex to reschedule the jobs after hours.
Hope this helps.
Saturday 16 May 2015
Alternate key for CRM 2015 spring release
Have you ever wished that CRM had a composite key to reference the entity data? Guess what your wishes are now granted With Spring release, CRM now makes keys available for all entities.
You can create a composite key/alternate key for multiple columns like Account Name + Account suburb or any such combinations. So the question in many people's mind would be how does this help?
With this, you can now define a non-clustered index in the database. This will allow quick searches as now non-clustered index can be created for alternate keys and that means table scans will not be necessary and the records can be fetched a lot faster.
This can also be used to identify data imported into CRM from external system. Please note alternate key is not GUID. It is new way to allow external systems store CRM reference.
Here is the code example which uses alternate keys
string accountNumber = "12345";
Money NewCreditLimit = new Money(5000000);
string newPrimaryContact = name1@company.com;
using (OrganizationServiceProxy service = GetOrgService())
{
Entity account = new Entity() { LogicalName = "account",
KeyAttributes = { { "new_subcode", "FABRIKAM" },
{ "new_subacctcode", accountNumber } }
};
account["primarycontactid"] = new EntityReference("contact", "emailaddress1", newPrimaryContact);
UpdateRequest request = new UpdateRequest();
request.Target = account;
UpdateResponse response = (UpdateResponse)service.Execute(request);
}
Further details on alternate keys available on following MSDN article:
https://msdn.microsoft.com/en-us/library/dn932139.aspx
Looking forward to more tightly integrated systems.
This can also be used to identify data imported into CRM from external system. Please note alternate key is not GUID. It is new way to allow external systems store CRM reference.
Here is the code example which uses alternate keys
string accountNumber = "12345";
Money NewCreditLimit = new Money(5000000);
string newPrimaryContact = name1@company.com;
using (OrganizationServiceProxy service = GetOrgService())
{
Entity account = new Entity() { LogicalName = "account",
KeyAttributes = { { "new_subcode", "FABRIKAM" },
{ "new_subacctcode", accountNumber } }
};
//update account
account["creditlimit"]
= NewCreditLimit;account["primarycontactid"] = new EntityReference("contact", "emailaddress1", newPrimaryContact);
UpdateRequest request = new UpdateRequest();
request.Target = account;
UpdateResponse response = (UpdateResponse)service.Execute(request);
}
Further details on alternate keys available on following MSDN article:
https://msdn.microsoft.com/en-us/library/dn932139.aspx
Looking forward to more tightly integrated systems.
Subscribe to:
Posts (Atom)