Dual-write Integration Key’s Nitty-Gritty

Dual-write allows the real-time integration of data between D365 CRM and F&O environments.

Well! While integrating two systems it is must that both the system knows how to find the respective record in other system’s table. This is where the Integration key comes into the picture.

Integration Key tells Dual-write engine, what columns to be taken into consideration while finding the respective record in D365 CRM.

Let me explain this with an example,

Consider in F&O there is a Customer (it synchronizes to the Account table in D365 CRM) with the Customer Number as DEMF001 and this has already been synchronized to D365 CRM. Now, next time if any update is made to the DEMF001 record in F&O the updated details should synchronize back to the right record. How will Dual-write engine know which is the respective record in D365 CRM? It is with the help of Integration Key. For this scenario I would configure the integration key as below.

Integration Key

Note: Company is equivalent to F&O’s Legal Entities.

Alternate Keys

Alternate Keys

Let us understand, how this is related to Alternate Keys in D365 CRM. In the D365 CRM, the main purpose of Alternate Key is to facilitate an integration with another system that usually do not use GUIDs as the primary key and have a different Primary Key. Also, Alternate Key in CRM makes sure that the value for the column(s) which is/are part of the Alternate Key is unique or else it will throw an error. It is best practice to define the Alternate Key and it will automatically be translated to as the Integration Key in Dual-Write.

Note: If your table has multiple Alternate Keys make sure to manually check the Integration Key whether the right one is applied or not.

Migrate Integration Key from one environment to another

The question whether the Integration Key can be transferred from one environment to another is quite a valid question, so to answer it yes, it is possible. However, it is not a straightforward process. For the Integration Key to be available at the destination environment, along with moving over the Dual-write mappings, you need to make sure that the table that you are trying to move has the Alternate Key defined with the right columns. Alternate Keys will then be translated as the Integration Key.


This way even the Integration Key would be automatically added.

Did you know Power Automate Flow supports C# code?

Power Automate flow is consistently evolving. At times there are UI changes or at times there are under the hood tweaks, but one thing is for sure Power Automate flow has matured a lot since its inception.

Today, in this blogpost, I will be discussing about the new feature that has been introduced recently in Power Automate.

Currently, we have plethora of connectors to choose from when it comes to getting our work done. However, there is also a way to create Custom Connector to bridge the gap with missing functionalities. The enhancement in question i.e., the usage of C# code has been made a part of the Custom Connector. Let me walk you through the process of creating a custom connector and the way to add the C# code. I will add the support of Math.Round, Math.Ceiling and Math.Floor using C#. With the introduction of C# support, we can do a lot many things.

Steps to create Custom Connector with C# code:

  • I will be adding this in the solution, so I will begin by creating a custom connector in the solution. The other way of creating a custom connector is by going to Data -> Custom Connector.
  • At the time of writing this blog, this feature is in Preview, meaning it is not recommended to be used in production.
Step 1:

In the solution where you want to add the Custom Connector, click on New -> Scroll to the bottom and click Other -> Select Custom Connector.

Add Custom Connector to the Solution.
Step 2:

Give a name to your Connector Math, provide a Description and a Host.

Host does not matter in the case of Custom Connector with C# code

Custom Connector General Tab
Step 3:

Let the Authentication Type be No Authentication.

Step 4:

On the Definition tab, Click on New action on the left-hand side. Create one with the below details.

Custom Connector Action General

For Ceiling and Floor Actions (while adding it later in the stage) replace Operation ID with MATH_CEILING and MATH_FLOOR respectively. Also, modify Summary and Description accordingly.

Store MATH_ROUND, MATH_CEILING and MATH_FLOOR for future use.

Step 5:

Add Request for the action, click on Import from sample.

Custom Connector Request

On the Import from sample screen, add the below details and click Import

Custom Connector Request Import

For feasibility, below is the JSON you can copy paste.

 "Number": 1.5

For the Ceiling & Floor Actions (while adding it later in the stage), replace URL with /math-ceiling and /math-floor respectively. Other details remain same.

Step 6:

Time to tweak the body a bit. Click on the 3 dots next to body.

Custom Connector Request Body

Now, click on 3 dots next to Number.

Custom Connector Request Parameter

Fill in the details as below,

Custom Connector Parameter Details
Step 7:

Time to define the Response. Click on Add default response.

Custom Connector Response

Add the values as below and click Import.

Custom Connector Response Details
  "value": 1.5
Step 8:

Edit Response by clicking on the three dots on value.

Custom Connector Response Value

Add the information as below,

Custom Connector Response Value Details
Step 9:

Click Create Connector and from time to time keep clicking on Update Connector for the changes to be saved.

Step 10:

Repeat Steps from 4 to 9 for Ceiling and Floor operations. 

Step 11:

Enable the Code and Select all the 3 Actions created before.

Custom Connector Code
Step 12:

Copy and paste the below code in the editor.

public class Script : ScriptBase
	public override async Task<HttpResponseMessage> ExecuteAsync()
		return await this.HandleMathOperation().ConfigureAwait(false);

	private async Task<HttpResponseMessage> HandleMathOperation()
		HttpResponseMessage response;
		// Get the Operation Id
        string operationId = (string)this.Context.OperationId;
		var contentAsString = await this.Context.Request.Content.ReadAsStringAsync().ConfigureAwait(false);

		// Parse as JSON object
		var contentAsJson = JObject.Parse(contentAsString);

		// Get the Number
		double number = (double)contentAsJson["Number"];
		// Based on the Operation Id perform the right action
        if(operationId == "MATH_ROUND")
			number = Math.Round(number);
        else if(operationId == "MATH_CEILING")
            number = Math.Ceiling(number);
		else if(operationId == "MATH_FLOOR")
			number = Math.Floor(number);      

		JObject output = new JObject
			["value"] = (float)number,

		response = new HttpResponseMessage(HttpStatusCode.OK);
		response.Content = CreateJsonContent(output.ToString());
		return response;
Step 13:

Update the connector and on the next step test the newly created connector.

Few things to note:
  1. Code takes precedence over codeless definition
  2. Only one C# script can be added per Custom Connector
  3. Code must be in C#
  4. Max execution time cannot execute 5 seconds
  5. File size cannot be more than 1 MB
  6. C# code needs to be tested locally

I feel even with the limitations stated above the opportunities that it opens is infinite.

Screenshot of the Power Automate Cloud Flow:

Power Automate Cloud Flow
%d bloggers like this: