Create, Update, and Upsert Multiple Web API Sample
This sample shows how to perform bulk create, update and upsert operations using the CreateMultiple, UpdateMultiple, and UpsertMultiple actions. These messages are optimized to provide the most performant way to create or update records with Dataverse.
This sample provides the option to use standard or elastic tables so you can compare the different performance characteristics.
This sample or the SDK version are prerequisites for the CreateMultiple and UpdateMultiple plug-ins Sample.
This sample is a Visual Studio .NET 6.0 solution that contains two projects (CreateUpdateMultiple and ParallelCreateUpdateMultiple) that perform the same operations in different ways so that you can compare the performance of each method.
The third UpsertMultiple project demonstrates bulk upsert of records and can use either standard or elastic tables.
You can find the sample here.
Prerequisites
- Microsoft Visual Studio 2022
- Access to Dataverse with system administrator or system customizer privileges.
How to run this sample
Clone or download the PowerApps-Samples repository.
Open the
PowerApps-Samples\dataverse\webapi\CSharp-NETx\xMultipleSamples.sln
file using Visual Studio 2022.This solution contains two projects that include these samples:
- CreateUpdateMultiple: Creates and updates a configurable number of records by sending two requests.
- ParallelCreateUpdateMultiple: Creates and updates a configurable number of records by sending requests in parallel.
- UpsertMultiple: Demonstrates upserting a configurable number of records.
Not
The WebAPIService project is included so that each of the other projects can depend on the common helper code provided by the service. The samples use several classes in the
WebAPIService/Messages
folder.In Solution Explorer, right-click the project you want to run and choose Set as Startup Project.
In any project, edit the
appsettings.json
file to set the following property values.Property Instructions Url
The URL for your environment. Replace the placeholder https://yourorg.api.crm.dynamics.com
value with the value for your environment. See View developer resources to find your URL.UserPrincipalName
Replace the placeholder you@yourorg.onmicrosoft.com
value with the UPN value you use to access the environment.Password
Replace the placeholder yourPassword
value with the password you use.Save the
appsettings.json
file.Not
Both projects refer to the same
appsettings.json
file, so you only need to replace with your values in one file to run either project.Press F5 to run the sample.
What this sample does
This sample is a .NET 6.0 Visual Studio 2022 solution that contains 2 projects (CreateUpdateMultiple and ParallelCreateUpdateMultiple) that perform the same operations.
Creates a new custom table named
sample_example
if it doesn't already exist.The table is created as a standard table by default. To create an elastic table, change the
UseElastic
property inSettings.cs
to true.Prepares a configurable number of entity instances for the custom table representing records to create.
Create the records. Each project uses a different method.
Updates the set of entity instances created by appending text to the
sample_name
attribute.Updates the records using the same method that created them.
Deletes the records using the BulkDelete action.
Deletes the custom
sample_example
table created in the first step. You can optionally remove the deletion.
Each project uses a shared set of settings in the Settings.cs
file that allow you to control:
UseElastic
: Whether to create and use an elastic table instead of a standard table.NumberOfRecords
: The number of records to create. The default value is 100 but you can raise it to 1000 or higher.StandardBatchSize
: The maximum number of records operations to send withCreateMultiple
andUpdateMultiple
.ElasticBatchSize
: The recommended number of records operations to send withCreateMultiple
andUpdateMultiple
for elastic tables is 100. You can use a higher or lower number, but a higher batch size isn't necessarily going to provide higher throughput because there is no transaction with elastic tables.BypassCustomPluginExecution
: Whether custom plugin logic should be bypassed. Bypassing is useful to observe the performance impact of plugins registered on events for the table.DeleteTable
: Whether to delete the customsample_example
table at the end of the sample. If you want to test plug-ins that use events on this table, you can instead preserve the table to run the samples multiple times while testing plugins.
The Settings.cs
file is included in both projects. Apply the change in one project and they're set for all projects.
Supporting examples
The shared Utility.cs
class contains static methods to perform operations that are common in each sample. These methods aren't the primary focus of the sample, but might be of interest:
Method | Description |
---|---|
TableExists |
Detects whether a table with the specified schema name exists. |
BulkDeleteRecordsByIds |
Asynchronously deletes a group of records for a specified table by ID. |
IsMessageAvailable |
Detects whether a specified message is supported for the specified table. |
CreateExampleTable |
Creates the table used by projects in this solution if it doesn't already exist. Currently uses Web API to create an elastic table. |
DeleteExampleTable |
Deletes the table used by projects in this solution, unless the DeleteTable setting is false. |
How this sample works
By default the CreateUpdateMultiple project is set as the startup project for the solution. To try the ParallelCreateUpdateMultiple or UpsertMultiple sample, right-click the project in Solution Explorer and choose Set as startup project.
Demonstrate
This sample demonstrates how to create and update records in bulk for a custom table created by the sample. The sample creates a custom table and cleans up when you finish running the sample.
Both projects in this solution send requests that includes:
- The optional
tag
parameter so that the name of the project is available to plugins as a shared variable. - The optional
BypassCustomPluginExecution
parameter to disable custom plugin execution so that the impact of any plugins registered for the operation can be compared. - A Stopwatch configured to capture the total duration of seconds for the request to complete.
Details about each project and the default output are described in their respective README files: