How to use OnExternalUpdated for Dataverse Virtual Entity

When we have already set up a Virtual Table/Entity in the Dataverse, sometimes there is a scenario when a data is being updated in the source system, it also needs to trigger the Dataverse Event (that contains our custom business logic). Today, we will learn how to enable Virtual Tables to support Dataverse events. In the documentation, we can see three Events that we can use: OnExternalCreatedOnExternalUpdated, and OnExternalDeleted.

Diagram how to use OnExternalUpdated

In the above diagram, you can see that when Transaction data is updated in External System, It needs to call Dataverse business logic (create Contact in Dataverse). So the point here is in Dataverse, we can’t trigger those plugin steps PreValidationUpdate – PostOperationUpdate for the Transaction table (if any). Because of the update from the source system itself and already handled by the Virtual Table Connector. But we can create an event for the Transaction table, to be called from the source system to ensure our custom business logic runs (if any).

Create Virtual Entity Metadata

If you already have a Virtual Table setup (if not yet, you can follow this link), go to make.powerapps.com > Solutions > select the solution that you want to use > New > More > Other > select Virtual Entity Metadata.

Create Virtual Entity Metadata

Once the page loaded, you can fill in the name > Select the Virtual Table that you have > set which Events that you want to turn on (Create, Update or Delete):

Fill in the Virtual Entity Metadata

If you have not set up this, when you want to register the plugin step (we will cover the detailed steps later), you can get the below error (Error sdkmessagefilter With Id = 5d7e1cf9-33d8-ec11-a7b5-0022481f4fb3 Does Not Exists):

If you have not set up Virtual Entity Metadata yet, the system will block you

Once done, you can click Save and go to the next step.

Create OnExternalUpdated Plugin for Transaction

Here is the sample code that I will trigger:

using Microsoft.Xrm.Sdk;
using System;

namespace DemoPlugin
{
    public class OnExternalCreatedTransactionVirtualEntity : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            var pluginExecutionContext = (IPluginExecutionContext)
                 serviceProvider.GetService(typeof(IPluginExecutionContext));

            var organizationServiceFactory = (IOrganizationServiceFactory)
                serviceProvider.GetService(typeof(IOrganizationServiceFactory));

            var adminService = organizationServiceFactory.CreateOrganizationService(null);

            var target = (Entity)pluginExecutionContext.InputParameters["Target"];
            var contact = new Entity("contact");
            contact["firstname"] = target.Id.ToString();
            contact["lastname"] = "External Update";

            adminService.Create(contact);
        }
    }
}

We want to create Contact once there is an update event from the source system (firstname = VirtualEntity.Id and lastname = “External Update”).

Then you can build it > open the Plugin Registration Tool > update/register the Plugin Assembly > right click on the Plugin class that we are creating > register new step and follow below setup:

Register the plugin step

Note: For events that we can set in Virtual Entity (OnExternalCreatedOnExternalUpdated, and OnExternalDeleted), we only can register them on PostOperation – Async.

Only Asynchronous plugin steps are allowed for virtual entity external events

Triggering OnExternalUpdated using CrmServiceClient

For the demonstration, I created the below code to run the business logic that we already setup:

using System;
using System.Web.Configuration;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Tooling.Connector;

namespace CrmCheck
{
    class Program
    {
        static void Main(string[] args)
        {
            CrmServiceClient.MaxConnectionTimeout = TimeSpan.FromHours(3);
            var connectionString = WebConfigurationManager.AppSettings["connectionString"];
            var client = new CrmServiceClient(connectionString);

            var update = new Entity("cra32_dbo_transaction",
                new Guid("3abebd6e-5db5-4d13-8417-3518667c5fdc"));
            update["cra32_name"] = "Update External";

            var request = new OrganizationRequest("OnExternalUpdated");
            request["Target"] = update;

            client.Execute(request);
            Console.ReadKey();
        }
    }
}

Once it is running, you can see the result:

Contact Created

Happy CRM-ing!

One thought on “How to use OnExternalUpdated for Dataverse Virtual Entity

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.