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: OnExternalCreated, OnExternalUpdated, and OnExternalDeleted.

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.

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):

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):

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:

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

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:

Happy CRM-ing!
One thought on “How to use OnExternalUpdated for Dataverse Virtual Entity”