DEVKIT1006 - phuocle/Dynamics-Crm-DevKit GitHub Wiki
This analyzer warns against using batch request types (ExecuteMultipleRequest, ExecuteTransactionRequest, CreateMultipleRequest, UpdateMultipleRequest, UpsertMultipleRequest) within plug-ins or workflow activities. These can cause performance issues, timeout errors, and transaction problems.
📚 Don't use batch request types in plug-ins and workflow activities
Batch requests used within a plug-in or workflow activity can become difficult to manage and may lead to performance issues. A plug-in runs within a database transaction. Calling additional batch requests within that transaction is not recommended.
Using batch requests in plugins causes:
- Extended Transactions: Batch operations extend the database transaction, increasing lock time
- Timeout Risks: Long-running batches may exceed the 2-minute plugin timeout
- Complexity: Error handling becomes more difficult with batched operations
- Nested Transactions: Batch requests create nested transaction scenarios
| Type | Description |
|---|---|
ExecuteMultipleRequest |
Executes multiple messages in a single request |
ExecuteTransactionRequest |
Executes multiple messages in a transaction |
CreateMultipleRequest |
Creates multiple records |
UpdateMultipleRequest |
Updates multiple records |
UpsertMultipleRequest |
Upserts multiple records |
The analyzer flags instantiation of batch request types within:
- Classes implementing
Microsoft.Xrm.Sdk.IPlugin - Classes inheriting from
System.Activities.CodeActivity - Classes inheriting from
System.Activities.NativeActivity
public class MyPlugin : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
var factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
var service = factory.CreateOrganizationService(null);
// ❌ Using ExecuteMultipleRequest in plugin
var batch = new ExecuteMultipleRequest
{
Requests = new OrganizationRequestCollection(),
Settings = new ExecuteMultipleSettings
{
ContinueOnError = false,
ReturnResponses = true
}
};
foreach (var entity in entitiesToUpdate)
{
batch.Requests.Add(new UpdateRequest { Target = entity });
}
service.Execute(batch); // This extends the transaction!
}
}public class MyPlugin : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
var factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
var service = factory.CreateOrganizationService(null);
// ✅ Execute each request individually
foreach (var entity in entitiesToUpdate)
{
service.Update(entity);
}
}
}- Replace with Individual Operations: Use individual Create/Update/Delete calls instead of batch
- Use Async Processing: For large data sets, trigger async processing outside the plugin
- Limit Scope: If processing multiple records, limit the count and queue remaining for async
- var batch = new ExecuteMultipleRequest();
- foreach (var entity in entities)
- {
- batch.Requests.Add(new UpdateRequest { Target = entity });
- }
- service.Execute(batch);
+ foreach (var entity in entities)
+ {
+ service.Update(entity);
+ }If you have a legitimate need to suppress this warning:
#pragma warning disable DEVKIT1006
var batch = new ExecuteMultipleRequest();
#pragma warning restore DEVKIT1006Or in .editorconfig:
[*.cs]
dotnet_diagnostic.DEVKIT1006.severity = suggestion| Property | Value |
|---|---|
| Rule ID | DEVKIT1006 |
| Category | DynamicsCrm.DevKit |
| Severity | Warning |
| Enabled by default | Yes |