Sunday, 29 December 2019

Microsoft Dynamics 365 - Helper Code and Syntax in C#





I have started writing this article for the developers (especially for the beginners) who is struggling to find the most common C# syntax in order to start writing the code in Dynamics 365.

So far, I have not seen any article on the internet contains all the code snippets and syntax used in Dynamics 365 at one place except MSDN (which sometimes not understandable for beginners may be).

This tutorial provides you all the sample code/syntax of C# (For Example : Perform CRUD operation in Dynamics CRM, How to make the connection with Dynamics CRM, Get/Set values from different types of attribute presents in CRM), which will help everyone to start writing code in Dynamics 365.

Note - I am still working on this article and have not yet provided all the code samples and syntax. Reason being, I don't want to keep you guys in waiting to start exploring the most common used syntax and code used in Dynamics 365

It might take too long to post all the code sample/syntax at one go..Hence, bookmark this article because I'll keep adding new code/syntax in the same article and will keep you guys posted about the same. Meanwhile enjoy this post and Many Thanks for your patience.

Stay Tuned and keep reading....

Syntax and Helper Code of Dynamics 365 in C#

Code to connect CRM Organization (C#):

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

ClientCredentials clientCredentials = new ClientCredentials();

clientCredentials.UserName.UserName = "<Username>";

clientCredentials.UserName.Password = "<Password>";

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

IOrganizationService organizationService = new OrganizationServiceProxy(new Uri("<CRM Organisation Service URL>"),

null, clientCredentials, null);

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Code to Create Record in CRM (C#):

Late Bound:

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// Instaniate an account object.
   Entity entityObj = new Entity("<Entity Logical Name>");

// Set the required attributes. For account entity, only the name is required. 

   
entityObj
["<Field 1 Logical Name (in lower case)>"] = "<value>";

   entityObj
["<Field 2 Logical Name (in lower case)>"] = "<value>";
   entityObj
["<Field 3 Logical Name (in lower case)>"] = "<value>";
// Syntax of creating record in CRM.

// service object has reference of CRM Organisation Service
// CRM Organisation Service use to make connection with CRM and perform various operations.

   Guid createdRecordUniqueId = service.Create(entityObj);



//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Early Bound:

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


//First Initiate Entity's Object by creating and adding Entity Metadata class in your code
// I am taking example of Account Entity        
Account account = new Account { 

Name = "Tata Consultancy Services",

Website = "www.tcs.com",
<Field 3 Scehma Name> = "<Value>",
<Field 4 Scehma Name> = "<Value>",
.
.
.
<Field N Scehma Name> = "<Value>"

};
// Syntax of creating record in CRM.
// service object has reference of CRM Organisation Service. 
// CRM Organisation Service use to make connection with CRM and perform various operations.          
Guid accountId = service.Create(account);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Note: 

  1. In Late Bound, we use Logical Name of Entity and it's attributes in the code, while in, Early Bound we use Schema Name of Entity and it's attributes.
  2. Logical Name of Entity and it's attributes always in lower case, while Schema name might be lower and upper case both.
  3. See this article to know the actual difference between Entity Logical and Schema name.


Code to Retrieve only single Record in CRM (C#):

or

Code to Retrieve a specific entity record through its Guid (C#):

If you have the GUID of any CRM record and you want to retrieve it's other field's data then you have to use the following syntax:

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


// Retrieve the record, if you have the GUID of that record
Entity recordReference = service.Retrieve("<Entity Logical Name>", <Record GUID>, attributes);



//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////





For Example, Let suppose, I have account guid and I want to retrieve that account's name,

website and other information through it's guid, then I would retrieve that information in following way:



// Suppose I know the accound Id. You might retrieve it dynamically in your code
Guid accountId = new Guid("4f7cd6-54c5-e811-a95d-000d3ab49476");

// Create a column set to define which attributes should be retrieved.
// If you have to retrieve data from all the fields then use below syntax
// ColumnSet attributes = new ColumnSet(true);
ColumnSet attributes = new ColumnSet(new string[] { "name", "website" });

// Retrieve the complete record through its Guid
Entity accoundRecord = service.Retrieve("account", accountId, attributes);

// Check whether the value exists in the field or not
// It is best practice to do a null check before retrieving any field's value
// Else we might get "Object reference" or"The given key was not present in the dictionary" error.
if(accoundRecord.Attributes.Contains("name"))
{
 string accountName = accoundRecord["name"].ToString();
}
// Check whether the value exists in the field or not
if(accoundRecord.Attributes.Contains("website"))
{
 string websiteURL = accoundRecord["website"].ToString();
}


Note
  1. A record can only be uniquely identified through its GUID because it is the only way that Microsoft recommends to uniquely identify the CRM record.
  2. For optimal performance don't use ColumnSet(true). You should only specify those fields/columns that needed by your application when querying Dynamics 365 for Customer Engagement data.
  3. All the fields from which you want to retrieve the data must be specified in the column set list, otherwise, you'll get "The given key was not present in the dictionary" error.
For Example:

// If I try retrieving value of field, which I have not declared in the column set list
string email = accoundRecord["email"].ToString();
This will through "The given key was not present in the dictionary" error, because I have not declared "email" field in column set list.


Code to Retrieve Multiple Records in CRM (C#)

If you have to retrieve the collection of record based on some query then we have to use RetrieveMultiple message.in CRM.
Basically, RetrieveMultiple message also invoked in all places in CRM like Advanced Find, Views, Lookup where the system is being queried for that particular entity.

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



//Entity from which we have to retrieve the records

QueryExpression query = new QueryExpression("<Entity Logical Name>");

//Create a column set to define which attributes should be retrieved.
query.ColumnSet.AddColumns("<field Name 1>", "<field Name 2>",......"<Field Name N>");
//Apply Conditions
query.Criteria = new FilterExpression(); query.Criteria.AddCondition("<field Name 1>", ConditionOperator.Equal, "<Value>");
query.Criteria.AddCondition("<field Name 1>", ConditionOperator.Equal, "<Value>");   
     
// Pass query to RetrieveMutiple to execute it and get the collection of record  
EntityCollection results = service.RetrieveMultiple(query);     
  
// Get results
foreach (var record in results.Entities)
{
string fieldName1 = record.GetAttributeValue<string>("<field Name 1>");
string fieldName2 = record.GetAttributeValue<string>("<field Name 2>")); 
}



//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////





For Example- Let suppose, I have to retrieve all contacts where firstname equal to Arpit and lastname equal to Shrivastava.

We all are familiar with SQL, hence we understand the query in the following way:

Select firstname, lastname from contact where firstname eq 'Arpit' & lastname eq 'Shrivastava'

Let's break this query in three parts:

  1. Select firstname, lastname - This is Column Set in CRM
  2. from contact - This is Query Expression in CRM
  3. where firstname eq 'Arpit' & lastname eq 'Shrivastava' - This is Condition Expression in CRM
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//from Contact

QueryExpression query = new QueryExpression("contact");



//Select firstname, lastname
query.ColumnSet.AddColumns("firstname", "lastname");



//where firstname eq 'Arpit' && lastname eq 'Shrivastava'
query.Criteria = new FilterExpression(); query.Criteria.AddCondition("firstname", ConditionOperator.Equal, "Arpit");

query.Criteria.AddCondition("lastname", ConditionOperator.Equal, "Shrivastava");   
     
// Pass query to RetrieveMutiple to execute it and get the collection of record  
EntityCollection results = service.RetrieveMultiple(query);     
  
// Get results
foreach (var record in results.Entities)

{

string firstName = record.GetAttributeValue<string>("firstname");
string lastName = record.GetAttributeValue<string>("lastname"); 
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

OR


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//from Contact
QueryExpression query = new QueryExpression("contact");

//Select firstname, lastname
query.ColumnSet.AddColumns("firstname", "lastname");

//where firstname eq 'Arpit'
ConditionExpression condition1 = new ConditionExpression();
condition1.AttributeName = "lastname";
condition1.Operator = ConditionOperator.Equal;
condition1.Values.Add("Shrivastava");

//lastname eq 'Shrivastava'
ConditionExpression condition2 = new ConditionExpression(); condition2.AttributeName = "firstname"; condition2.Operator = ConditionOperator.Equal; condition2.Values.Add("Arpit"); FilterExpression filter1 = new FilterExpression(); filter1.Conditions.Add(condition1); filter1.Conditions.Add(condition2);

query.Criteria.AddFilter(filter1);
// Pass query to RetrieveMutiple to execute it and get the collection of record 
EntityCollection results = service.RetrieveMultiple(query);     
  
// Get results
foreach (var record in results.Entities)
{
string firstName = record.GetAttributeValue<string>("firstname");
string lastName = record.GetAttributeValue<string>("lastname"); 
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Use AND and OR operators in Query Expression?

Query : Select firstname, lastname, emailaddress1, emailaddress2 from contacts where (firstname eq 'Arpit' AND lastname eq 'Shrivastava') OR (emailaddress1 eq 'arpit.shri@tcs.com' AND emailaddress2 eq 'arpit.crmconsultant@gmail.com')
/////////////////////////////////////////////////////////////Start///////////////////////////////////////////////////////////////////////////

//from Contact
QueryExpression query = new QueryExpression("contact");

//Select firstname, lastname
query.ColumnSet.AddColumns("firstname", "lastname","emailaddress1", "emailaddress2");

FilterExpression filter = new FilterExpression(LogicalOperator.Or);

FilterExpression filter1 = new FilterExpression(LogicalOperator.And);
filter1.Conditions.Add(new ConditionExpression("firstname", ConditionOperator.Equal, "Arpit"));
filter1.Conditions.Add(new ConditionExpression("lastname", ConditionOperator.Equal, "Shri"));

FilterExpression filter2 = new FilterExpression(LogicalOperator.And);
filter2.Conditions.Add(new ConditionExpression("emailaddress1", ConditionOperator.Equal, "arpit.shri@tcs.com"));
filter2.Conditions.Add(new ConditionExpression("emailaddress2", ConditionOperator.Equal, "arpit.crmconsultant@gmail.com"));

filter.AddFilter(filter1);
filter.AddFilter(filter2);

query.Criteria = filter;

// Pass query to RetrieveMutiple to execute it and get the collection of record 
EntityCollection results = service.RetrieveMultiple(query);     
  
// Get results
foreach (var record in results.Entities)
{
string firstName = record.GetAttributeValue<string>("firstname");
string lastName = record.GetAttributeValue<string>("lastname")); 
}
/////////////////////////////////////////////////////////////////
End
//////////////////////////////////////////////////////////////////////////


Code to Update Record in CRM (C#):

In order to update the record's data in CRM, you must know about the Record first. And record can be retrieve through it's unique id i;e, it's Guid.
If you know the record's guid then you can directly update it's data in following way:
In Example, I have hard-coded the record Guid, however In real time, you can get this dynamically.

Update Single Record:

/////////////////////////////////////////////////////////////////
Start
/////////////////////////////////////////////////////////////////////////


// Unique Id of Record that has to be updated

// For demonstration, I have hard-coded the record guid. You can get this dynamically also

Guid 
recordGuid 
= bew Guid("
4f7cd6-54c5-e811-a95d-000d3ab49476
");



// Attributes list that have to be updated.
ColumnSet attributes = new ColumnSet(new string[] {"field1", "field2"});

 // Retrieve the record and its attributes that have to be updated
Entity entityObj = service.Retrieve("<Entity Logical Name>", recordGuid, attributes);
                    
// Update the field1 value.
entityObj["field1"] = "<Updated Value>";

// Update the field2 value.
entityObj["field2"] = "<Updated Value>";

// Update the record.
service.Update(entityObj);

/////////////////////////////////////////////////////////////////
End
//////////////////////////////////////////////////////////////////////////


For Example: I am creating an account and later I want to update it's name and website url.


/////////////////////////////////////////////////////////////////
Start
/////////////////////////////////////////////////////////////////////////



// Instantiate Entity Name 
Entity account = new Entity("account");


// Set the name. 

 account["name"] = "Tata Consultancy Services";




// Set the website url 
account["website"] = "www.tcs.com";
// Create an account record and get its unique Id. Guid accountId = service.Create(account);



// Now, If we want to update the above account account, we need its guid
// Since We already got the created account Id, Lets update the record






// Declare Attributes list that has to be updated.
// If you don't declare the field name here and try to update it, you'll get an error"
ColumnSet attributes = new ColumnSet(new string[] {"name","website"});



 // Retrieve the record and its attributes that have to be updated
Entity accountObj = service.Retrieve("account",accountId, attributes);
                    
// Update the account name.
accountObj
["
name
"] = "Microsoft"; // Update the website url.
accountObj
["
website
"] = "www.microsoft.com"; // Update the record. service.Update(
accountObj
);


/////////////////////////////////////////////////////////////////
End
//////////////////////////////////////////////////////////////////////////


Update Multiple Records:

Let suppose, I have to update the emailaddress of all the contacts having firstname equal Alex


/////////////////////////////////////////////////////////////////Start//////////////////////////////////////////////////////////////////////////

//from Contact
QueryExpression query = new QueryExpression("contact");

//Select firstname, lastname
query.ColumnSet.AddColumns("firstname", "emailaddress1");

//where firstname eq 'Arpit' && lastname eq 'Shrivastava'
query.Criteria = new FilterExpression();
query.Criteria.AddCondition("firstname", ConditionOperator.Equal, "Alex");

// Pass query to RetrieveMutiple to execute it and get the collection of record  
EntityCollection results = service.RetrieveMultiple(query);

// Get results
foreach (var record in results.Entities)
{
 record["emailaddress1"] = "alex.simmons@hotmail.com";

 service.Update(record);

 Console.WriteLine("Records has been updated successfully");
                
}

Console.ReadKey();



/////////////////////////////////////////////////////////////////
End
//////////////////////////////////////////////////////////////////////////


Code to Delete Record in CRM (C#)

Let suppose, I have to delete the account having name equal Tata Consultancy Services


/////////////////////////////////////////////////////////////////Start//////////////////////////////////////////////////////////////////////////

public static void Main(string[] args)
{
  
DeleteRecord(new Guid("F5E41362-8432-E911-A97A-000D3AF24324")); }

// Delete the account.
bool deleteRecords = true;

Console.WriteLine("\nDo you want these entity record(s) deleted? (y/n) [y]: ");
String answer = Console.ReadLine();

deleteRecords = (answer.StartsWith("y") || answer.StartsWith("Y") || answer == String.Empty);

if(deleteRecords)
{
 service.Delete("account", _accountId);

 Console.WriteLine("Entity record(s) have been deleted.");

 Console.ReadKey();
            
}

/////////////////////////////////////////////////////////////////
End
//////////////////////////////////////////////////////////////////////////


Code to Assign Record in CRM (C#)

In order to assign the record in CRM using C# or JavaScript, we have to remember following:

Assignee - To whom the record would be assigned. It would be either Team or User
Target - What needs to be assigned. Means it's a record that we are going to assign to Team/User.

Here is the syntax of the same:


 // Assign the account to a team.                
  AssignRequest assignRequest = new AssignRequest()
  {
   Assignee = new EntityReference
   {


    LogicalName = "<entitylogicalname>", //Entity Logical name: systemuser or team
    

    Id = <Guid of Team/User> // Guid of team or user to whom record would be assigned

   },

   Target = new EntityReference("account", <Guid of record that needs to be assigned>)
 };

 service.Execute(assignRequest);

/////////////////////////////////////////////////////////////////Start//////////////////////////////////////////////////////////////////////////

public static void Main(string[] args) 
{
//Guid of Team
Guid teamId = new Guid("AD405F7F-0120-E911-A97D-000D3AF245FB");
//Guid of User
Guid userId = new Guid("AD405F7F-0120-E911-A97D-000D3AF245FB")
//Assign accound record to Team
AssignRecord("account",new Guid("A8A19CDD-88DF-E311-B8E5-6C3BE5A8B200"),"team", teamId);
//Assign accound record to User
AssignRecord("account", new Guid("A8A19CDD-88DF-E311-B8E5-6C3BE5A8B200"), "systemuser", userId);

 

}

public static void AssignRecord(string Target_EntityLogicalName, Guid Target_RecordId, string AssignTo_UserOrTeam, Guid AssignTo_UserIdOrTeamId)
{
  // Assign the account to a team.                
  AssignRequest assignRequest = new AssignRequest()
  {
   Assignee = new EntityReference
   {
    LogicalName = AssignTo_UserOrTeam,
    Id = AssignTo_UserIdOrTeamId
   },

   Target = new EntityReference(Target_EntityLogicalName, Target_RecordId)
 };

 service.Execute(assignRequest);

 Console.WriteLine("The account has been assigned to the team/user.");

 Console.ReadKey();
}

/////////////////////////////////////////////////////////////////End//////////////////////////////////////////////////////////////////////////
Note
  1. Before assigning the record in CRM from one User/Team to another, make sure both the parties are having Read Privilege on that particular entity otherwise you'll get access permission issue.

Code to Share Record in CRM (C#)

I have seen people get confused between Assigning the Record and Sharing the Record in CRM..
However, the difference is only of Ownership. By assigning the record, ownership of that record gets changed while By Sharing the record, ownership remains same, you only make that record accessible to others with limited rights. Anytime, you can Modify and Revoke the access as well.
Let's understand the concept of Record Sharing and Record Ownership through these two Pics.

My Pizza is My Pizza

I am Sharing my Pizza with others

  • When security settings prevent some users from seeing or editing all records in the Dynamics 365, it may be necessary to share records that require collaboration across teams. When sharing, you can share the view, edit, assign, or delete rights as long as you have them yourself.
  • The relationship between an access right and a privilege is that access rights apply only after privileges have taken effect. For example, if a user does not have the privilege to read accounts, that user is unable to read any account, regardless of the access rights another user might grant to a specific account through sharing.
  • When you share a record with another user, indicate what access rights (Read, Write, Delete, Append, Assign, and Share) you want to grant to the other user. Access rights on a shared record can be different for each user with whom the record is shared. However, you cannot give a user any rights that he or she would not have for that type of entity, based on the role assigned to that user. For example, if a user does not have Read privileges on accounts and you share an account with that user, the user will be unable to see that account.
  • A user might have access to the same record in more than one context. For example, a user might share a record directly with specific access rights, and he or she might also be on a team in which the same record is shared with different access rights. In this case, the access rights that this user has on the record are the union of all the rights.
  • Note when you share a record with a group you are only making the record accessible to them and for all other purposes the owner is still the original user and a single user at that.


/////////////////////////////////////////////////////////////////Start//////////////////////////////////////////////////////////////////////////

public static void Main(string[] args)
{
  
 Guid TargetRecordId = new Guid("DC9E62A8-90DF-E311-9565-A45D36FC5FE8");

 Guid teamId = new Guid("AD405F7F-0120-E911-A97D-000D3AF245FB");

 ShareRecord("incident", TargetRecordId, "team", teamId);
        

}


public static void ShareRecord(string Target_EntityLogicalName, Guid Target_RecordId, string ShareTo_EntityLogicalName, Guid ShareTo_RecordId)
{
   // Team/User, to whom record has to share
   var ShareTo_UserOrTeam = new EntityReference(ShareTo_EntityLogicalName, ShareTo_RecordId);
                
   var grantAccessRequest = new GrantAccessRequest
   {
    PrincipalAccess = new PrincipalAccess
    {
      // Grant the team read/write access on the shared record.
      AccessMask = AccessRights.ReadAccess | AccessRights.WriteAccess,
      Principal = ShareTo_UserOrTeam
    },
      Target = new EntityReference(Target_EntityLogicalName, Target_RecordId)
                
   };

      service.Execute(grantAccessRequest);

      Console.WriteLine("The record has been shared to the team/user");

      Console.ReadKey();



// Example of Modifying the team/user access on the shared record.
// First we have given read/write access now Granting the user delete access to the lead.
      
      var modifyUserAccessReq = new ModifyAccessRequest
      {
        PrincipalAccess = new PrincipalAccess
        {
         AccessMask = AccessRights.DeleteAccess,
         Principal = ShareTo_UserOrTeam
        },
         Target = new EntityReference(Target_EntityLogicalName, Target_RecordId)
      };

      service.Execute(modifyUserAccessReq);

      Console.WriteLine("User/Team has been given access to Delete the record");

      Console.ReadKey();

// Example of Revoking the Share access that we had given to User/Team in above code
      
      var revokeUserAccessReq = new RevokeAccessRequest
      {
       // User/Team, with whom we shared the record
       Revokee = new EntityReference("team", new Guid("AD405F7F-0120-E911-A97D-000D3AF245FB")),
       Target = new EntityReference(Target_EntityLogicalName, Target_RecordId)
      };
             
       service.Execute(revokeUserAccessReq);

       Console.WriteLine("User/Team Sharing access has been revoked");

       Console.ReadKey();

}


/////////////////////////////////////////////////////////////////End//////////////////////////////////////////////////////////////////////////

Code to Associate Record in CRM (C#)


I am taking example of Associating the Various Accounts with a Contact record.


/////////////////////////////////////////////////////////////////Start//////////////////////////////////////////////////////////////////////////


public static void Main(string[] args)

{
  AssociateRecord();

}

public static void AssociateRecord()
{
   // Define the IDs needed for this sample.
   Guid _contactId = new Guid("25A17064-1AE7-E611-80F4-E0071B661F01");
   Guid _account1Id = new Guid("B4A19CDD-88DF-E311-B8E5-6C3BE5A8B200");
   Guid _account2Id = new Guid("ACA19CDD-88DF-E311-B8E5-6C3BE5A8B200"); ;
   Guid _account3Id = new Guid("A8A19CDD-88DF-E311-B8E5-6C3BE5A8B200"); ;

   // Associate the accounts to the contact record.

   // Create a collection of the entities that will be 
   // associated to the contact.
   EntityReferenceCollection relatedEntities = new EntityReferenceCollection();
   relatedEntities.Add(new EntityReference("account", _account1Id));
   relatedEntities.Add(new EntityReference("account", _account2Id));
   relatedEntities.Add(new EntityReference("account", _account3Id));

   // Create an object that defines the relationship between the contact and account.
   Relationship relationship = new Relationship("account_primary_contact");

   //Associate the contact with the 3 accounts.
   service.Associate("contact", _contactId, relationship, relatedEntities);

   Console.WriteLine("Accounts has been associated with Contact successfully...");
   Console.Read();

}




/////////////////////////////////////////////////////////////////End//////////////////////////////////////////////////////////////////////////


Code to Dis-associate Record in CRM (C#)

I am taking example of Disassociating the Various Accounts from a Contact record.



/////////////////////////////////////////////////////////////////Start//////////////////////////////////////////////////////////////////////////


public static void Main(string[] args)

{
  DisassociateRecord();

}



public static void DisassociateRecord()
{
   // Define the IDs needed for this sample.
   Guid _contactId = new Guid("25A17064-1AE7-E611-80F4-E0071B661F01");
   Guid _account1Id = new Guid("B4A19CDD-88DF-E311-B8E5-6C3BE5A8B200");
   Guid _account2Id = new Guid("ACA19CDD-88DF-E311-B8E5-6C3BE5A8B200"); ;
   Guid _account3Id = new Guid("A8A19CDD-88DF-E311-B8E5-6C3BE5A8B200"); ;

   // Associate the accounts to the contact record.

   // Create a collection of the entities that will be 
   // associated to the contact.
   EntityReferenceCollection relatedEntities = new EntityReferenceCollection();
   relatedEntities.Add(new EntityReference("account", _account1Id));
   relatedEntities.Add(new EntityReference("account", _account2Id));
   relatedEntities.Add(new EntityReference("account", _account3Id));

   // Create an object that defines the relationship between the contact and account.
   Relationship relationship = new Relationship("account_primary_contact");

   //Associate the contact with the 3 accounts.
   service.Disassociate("contact", _contactId, relationship, relatedEntities);

   Console.WriteLine("Accounts has been disassociated with Contact successfully...");
   Console.Read();

}


/////////////////////////////////////////////////////////////////End//////////////////////////////////////////////////////////////////////////

Set value in all types of CRM attributes while creating record in CRM (C#)


/////////////////////////////////////////////////////////////////Start//////////////////////////////////////////////////////////////////////////

public static void Main(string[] args)
{
     CreateRecord();
}


public static void CreateRecord()
{
  // Instaniate an entity object.
     Entity account = new Entity("account");

  // Set String value
     account["name"] = "Tata Consultancy Services ";

  // Set Date Time value
     account["lastonholdtime"] = new DateTime(2019, 02, 25); // or DateTime.Now; for current date time

 // Set Option Set value
     account["preferredcontactmethodcode"] = new OptionSetValue(2);

 // Set Two Options/Boolean value
     account["donotemail"] = true;

 // Set Lookup type field value
     account["parentaccountid"] = new EntityReference("account", new Guid("80FF91E0-DD38-E911-A979-000D3AF24950"));

 // Set Multiline Text type value
     account["description"] = "Tata Consultancy Services Limited";

 // Set Money type value
     account["openrevenue"] = new Money(700.2M);

 // Set Integer type value
     account["opendeals"] = 10;

 // Set Decimal type value
     account["exchangerate"] = 0.18;

 // Set Currency type field value
     EntityReference currencyType = new EntityReference();
     currencyType.Id = new Guid("E708F7DC-1620-E911-A981-000D3AF245D0"); // Guid of 'Euro' currency
     currencyType.LogicalName = "transactioncurrency"; // Currency Entity Name
     account.Attributes.Add("transactioncurrencyid", currencyType);
            
 // Set Customer type field value
     account["new_customer"] = new EntityReference("contact", new Guid("25A17064-1AE7-E611-80F4-E0071B661F01"));

 // Set Float type field value
     account["new_floatfield"] = 0.15;

 // Set value in Multi select optionset type field
 //To set Single values
     OptionSetValueCollection collectionOptionSetValues = new OptionSetValueCollection();
     OptionSetValue optionSet = new OptionSetValue(1); // set option set value  
     collectionOptionSetValues.Add(optionSet);
     account["new_mutiselectoptionfield"] = collectionOptionSetValues

 //TO set Multiple values
   //OptionSetValueCollection collectionOptionSetValues = new OptionSetValueCollection();
   //string[] arr = { "1", "2" }; // mention option set values here
   //foreach (var item in arr)
   //{
   //    collectionOptionSetValues.Add(new OptionSetValue(Convert.ToInt32(item)));
   //}
   //account["new_mutiselectoptionfield"] = collectionOptionSetValues;


 // Set value in Owner Field
    account["ownerid"] = new EntityReference("systemuser", new Guid("D72D8D9E-FCEC-4C6B-8340-A2CB9FAA88D5"));

 // Create an account record named Fourth Coffee.
    Guid _accountId = service.Create(account);

    Console.Write("Record has been created succeefully with Id: " + _accountId.ToString());

    Console.Read();
        
}


/////////////////////////////////////////////////////////////////End//////////////////////////////////////////////////////////////////////////

Code to Check if a specific attribute present in an entity (C#)

In Dynamics 365, It is best practice to check whether any attribute exists in CRM or not before retrieving it's value and use it further.
Let say you are retrieving the name field value of Account entity. And by-mistakenly, I have typed the attribute name wrong (name1 instead of name) and try to retrieving it's value without checking the attribute name then see what happens:






Hence, you must use following syntax to retrieve the attribute value.

// Before retrieving the name,Check whether the 'name' attribute exists in 'account' entity
// else, we will get 'The given key was not present in the dictionary error' or
// Object reference not set an instance of an object

Entity account = service.Retrieve("account", accountGuid, new ColumnSet("name"));

if(account.Attributes.Contains("name"))
{
 string accountName = account["name"].ToString();
}

In above syntax, If conditions checks whether the name field exists in account entity or not. If returns True then retrieve it's value else come out of If block. But, it will not throw the exception.

There is one more easiest way provided by Microsoft in order to check the attribute before retrieving it's value: Here it is:
Entity account = service.Retrieve("account", accountGuid, new ColumnSet("name"));
String name = account.GetAttributeValue<String>("name");


Now benefit of having above syntax is, you don't need to use If-Else block or need to check for null value of any attribute. This syntax, checks whether the attribute exists or not, If not, it returns Null instead of throwing exception.
To understand the more difference between above two syntaxes please check following article:

Code to Get Value of all the types of attribute in CRM (C#)

public static void RetrieveSingleRecord()
{
  Entity account = service.Retrieve("account", new Guid("A124F3E1-0139-E911-A979-000D3AF24950"), new ColumnSet(true));

  // Get text or string field value
  String name = account.GetAttributeValue<String>("name");

  // Set Date Time Field value
  DateTime lastonholdtime = account.GetAttributeValue<DateTime>("lastonholdtime");

  // Set Option Set value
  int preferredcontactmethod_Value = account.GetAttributeValue<OptionSetValue>("preferredcontactmethodcode").Value;
  string preferredcontactmethod_Text = account.FormattedValues["preferredcontactmethodcode"].ToString();

  // Set Two Options/Boolean value
  bool donotemail = account.GetAttributeValue<bool>("donotemail");

  // Set Lookup type field value
  EntityReference parentaccount = account.GetAttributeValue<EntityReference>("parentaccountid");
  Guid parentAcccountGuid = parentaccount.Id;
  string parentAcccountName = parentaccount.Name;

  // Set Multiline Text type value
  string description = account.GetAttributeValue<string>("description");

  // Set Money type value
  Decimal openrevenue = account.GetAttributeValue<Money>("openrevenue").Value;

  // Set Integer type value
  int opendeals = account.GetAttributeValue<int>("opendeals");

  // Set Decimal type value
  Decimal exchangerate = account.GetAttributeValue<Decimal>("exchangerate");

  // Set Currency type field value
  EntityReference transactioncurrency = account.GetAttributeValue<EntityReference>("transactioncurrencyid");
  Guid transactioncurrencyId = transactioncurrency.Id;
  string transactioncurrencyName = transactioncurrency.Name;

  // Set Customer type field value
  EntityReference customerfield = account.GetAttributeValue<EntityReference>("new_customer");
  Guid customerfieldId = customerfield.Id;
  string customerfieldName = customerfield.Name;

  // Set Float type field value
  Double val = account.GetAttributeValue<Double>("new_floatfield");

  // Set value in Multi select optionset type field
  OptionSetValueCollection mutiselectoptionfield = account.GetAttributeValue<OptionSetValueCollection>("new_mutiselectoptionfield");

  foreach (var multioptions in mutiselectoptionfield)
  {
   int i = multioptions.Value;               
  }
            
  Console.WriteLine("Account details has been retrieved successfully...");
  Console.Read();

        
}
Code to Retrieve record using paging if records to retrieve is more than 5000 (C#)

In Dynamics 365 for Customer Engagement Customer Engagement, you can use the paging cookie feature to make paging in an application faster for large datasets. The feature is available in both FetchXML and QueryExpression queries. 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.



For Example, I am retrieving all contact records from CRM, which is 5000+ in count,

Using Query Expression:

class CRMCodeHelper
    {
        static IOrganizationService crmservice = null;
        static void Main(string[] args)
        {
            try
            {
                crmservice = ConnectCRM();

                RecordPaging_QueryExpression();

            }
            catch(Exception ex)
            {
                Console.WriteLine("The application terminated with an error.");
                Console.WriteLine(ex.Message);
               
            }
            finally
            {
                Console.WriteLine("Press <Enter> to exit.");
                Console.ReadLine();
            }
            
        }

public static void RecordPaging_QueryExpression()
{
            // Query using the paging cookie.
            // Define the paging attributes.
            // The number of records per page to retrieve.
            int queryCount = 5000;

            // Initialize the page number.
            int pageNumber = 1;

            // Initialize the number of records.
            int recordCount = 0;

            //from Contact
            QueryExpression query = new QueryExpression("contact");

            //Select firstname, lastname
            query.ColumnSet.AddColumns("firstname", "lastname","emailaddress1");

            // Assign the pageinfo properties to the query expression.
            query.PageInfo = new PagingInfo();
            query.PageInfo.Count = queryCount;
            query.PageInfo.PageNumber = pageNumber;

            // The current paging cookie. When retrieving the first page, 
            // pagingCookie should be null.
            query.PageInfo.PagingCookie = null;
            Console.WriteLine("Retrieving sample contact records in pages...\n");
            Console.WriteLine("#\tContact Name\t\tEmail Address");


            while (true)
            {
                // Pass query to RetrieveMutiple to execute it and get the collection of record 
                EntityCollection results = crmservice.RetrieveMultiple(query);

                if (results.Entities != null)
                {
                    // Get results
                    foreach (var contact in results.Entities)
                    {
                        string firstName = contact.GetAttributeValue<string>("firstname");

                        string lastName = contact.GetAttributeValue<string>("lastname");

                        string email = contact.GetAttributeValue<string>("lastname");

                        Console.WriteLine("{0}.\t{1}\t{2}", ++recordCount, firstName+" "+lastName, email);
                    }
                }

                // Check for more records, if it returns true.
                if (results.MoreRecords)
                {
                    Console.WriteLine("\n****************\nPage number {0}\n****************", query.PageInfo.PageNumber);
                    Console.WriteLine("#\tContact Name\t\tEmail Address");

                    // Increment the page number to retrieve the next page.
                    query.PageInfo.PageNumber++;

                    // Set the paging cookie to the paging cookie returned from current results.
                    query.PageInfo.PagingCookie = results.PagingCookie;
                }
                else
                {
                    // If no more records are in the result nodes, exit the loop.
                    break;
                }
            }
        }
}


Using Fetch XML:

class CRMCodeHelper
    {
        static IOrganizationService crmservice = null;
        static void Main(string[] args)
        {
            try
            {
                crmservice = ConnectCRM();

                RecordPaging_FetchXML();


            }
            catch(Exception ex)
            {
                Console.WriteLine("The application terminated with an error.");
                Console.WriteLine(ex.Message);
               
            }
            finally
            {
                Console.WriteLine("Press <Enter> to exit.");
                Console.ReadLine();
            }
            
        }


public static void RecordPaging_FetchXML()
        {
            // Define the fetch attributes.
            // Set the number of records per page to retrieve.
            int fetchCount = 3;
            // Initialize the page number.
            int pageNumber = 1;
            // Initialize the number of records.
            int recordCount = 0;
            // Specify the current paging cookie. For retrieving the first page, 
            // pagingCookie should be null.
            string pagingCookie = null;

            //from Contact

            string fetchXml = string.Format(@"<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>
<entity name='contact'>
<attribute name='emailaddress1' />
<attribute name='contactid' />
<attribute name='lastname' />
<attribute name='firstname' /
<order attribute='emailaddress1' descending='false' />
<filter type='and'>
<condition attribute='statecode' operator='eq' value='0' />
</filter>
</entity>
</fetch>");
          
            Console.WriteLine("Retrieving sample contact records in pages...\n");
            Console.WriteLine("#\tContact Name\t\tEmail Address");
            while (true)
            {
                // Build fetchXml string with the placeholders.
                string xml = CreateFetchXml(fetchXml, pagingCookie, pageNumber, fetchCount);

                // Excute the fetch query and get the xml result.
                RetrieveMultipleRequest fetchRequest1 = new RetrieveMultipleRequest
                {
                    Query = new FetchExpression(xml)
                };

                EntityCollection returnCollection = ((RetrieveMultipleResponse)crmservice.Execute(fetchRequest1)).EntityCollection;

                foreach (var contact in returnCollection.Entities)
                {
                    System.Console.WriteLine("{0}.\t{1}\t\t{2}", ++recordCount, contact.Attributes["firstname"], contact.Attributes["emailaddress1"]);
                }

                // Check for morerecords, if it returns 1.
                if (returnCollection.MoreRecords)
                {
                    Console.WriteLine("\n****************\nPage number {0}\n****************", pageNumber);
                    Console.WriteLine("#\tAccount Name\t\t\tEmail Address");

                    // Increment the page number to retrieve the next page.
                    pageNumber++;

                    // Set the paging cookie to the paging cookie returned from current results.                            
                    pagingCookie = returnCollection.PagingCookie;
                }
                else
                {
                    // If no more records in the result nodes, exit the loop.
                    break;
                }
            }

        }
}


public static string CreateFetchXml(string xml, string cookie, int page, int count)
        {
            StringReader stringReader = new StringReader(xml);
            XmlTextReader reader = new XmlTextReader(stringReader);

            // Load document
            XmlDocument doc = new XmlDocument();
            doc.Load(reader);

            XmlAttributeCollection attrs = doc.DocumentElement.Attributes;

            if (cookie != null)
            {
                XmlAttribute pagingAttribute = doc.CreateAttribute("paging-cookie");
                pagingAttribute.Value = cookie;
                attrs.Append(pagingAttribute);
            }

            XmlAttribute pageAttribute = doc.CreateAttribute("page");
            pageAttribute.Value = System.Convert.ToString(page);
            attrs.Append(pageAttribute);

            XmlAttribute countAttribute = doc.CreateAttribute("count");
            countAttribute.Value = System.Convert.ToString(count);
            attrs.Append(countAttribute);

            StringBuilder sbuilder = new StringBuilder(1024);
            StringWriter stringWriter = new StringWriter(sbuilder);

            XmlTextWriter writer = new XmlTextWriter(stringWriter);
            doc.WriteTo(writer);
            writer.Close();

            return sbuilder.ToString();
        }


To be continued...


Cheers. 

Stay Tuned !! Will keep you posted for further updates...

13 comments:

  1. Almost you have covered all the scenarios of CRM plugin. Awesome info.

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. How Lemeridian funding service  grant me a loan!!!

    Hello everyone, I'm Lea Paige Matteo from Zurich Switzerland and want to use this medium to express gratitude to lemeridian funding service for fulfilling his promise by granting me a loan, I was stuck in a financial situation and needed to refinance and pay my bills as well as start up a Business. I tried seeking for loans from various loan firms both private and corporate organisations but never succeeded and most banks declined my credit request. But as God would have it, I was introduced by a friend named Lisa Rice to Le_meridian funding service and undergone the due process of obtaining a loan from the company, to my greatest surprise within 48hrs just like my friend Lisa, I was also granted a loan of $216,000.00 So my advise to everyone who desires a loan, "if you must contact any firm with reference to securing a loan online with low interest rate of 1.9% and better repayment plans/schedule, please contact Le_meridian funding service. Besides, he doesn't know that am doing this but due to the joy in me, I'm so happy and wish to let people know more about this great company whom truly give out loans, it is my prayer that GOD should bless them more as they put smiles on peoples faces. You can contact them via email on {lfdsloans@lemeridianfds.com Or lfdsloans@outlook.com} or Text through Whatsapp +1-989 394 3740.

    ReplyDelete
  4. This is a great post, I love the way you explain all the cocepts of CRM in Microsoft dynamics.
    I would love to explain some of the concepts on my free CRM blog .

    ReplyDelete
  5. Nice blog. You have provided such a useful information in this blog. Thanks for sharing.
    D365 Finance and Operations Training
    D365 Finance and Operations Training in Hyderabad
    D365 Operations Training

    ReplyDelete
  6. It's an amazing paragraph in favor of all the online viewers; they will take benefit from it I am sure.

    ReplyDelete
  7. Special thanks to (hackingsetting50@gmail.com) for exposing my cheating husband. Right with me i got a lot of evidences and proofs that shows that my husband is a fuck boy and as well a cheater ranging from his text messages, call logs, whats-app messages, deleted messages and many more, All thanks to

    (hackingsetting50@gmail.com), if not for him i will never know what has been going on for a long time.

    Contact him now and thank me later.

    ReplyDelete
  8. Special thanks to (hackingsetting50@gmail.com) for exposing my cheating husband. Right with me i got a lot of evidences and proofs that shows that my husband is a fuck boy and as well a cheater ranging from his text messages, call logs, whats-app messages, deleted messages and many more, All thanks to

    (hackingsetting50@gmail.com), if not for him i will never know what has been going on for a long time.

    Contact him now and thank me later.

    ReplyDelete

Blogger Widgets