How to Deactivate Child Records Using Plug-in in Dynamics 365
```htmlHow to Deactivate Child Records Using Plug-in in Dynamics 365
In Dynamics 365 and Dataverse, organizations often maintain parent-child relationships between records. When a parent record becomes inactive, the associated child records should also be deactivated automatically.
For example:
- Account → Contacts
- Project → Project Tasks
- Customer → Service Requests
- Opportunity → Opportunity Products
If child records remain active while the parent record is inactive, it can lead to inconsistent data and business process issues.
One of the most effective ways to automate this behavior is by using a Dynamics 365 Plug-in.
Why Deactivate Child Records?
Consider the following scenario:
Parent Record
Account = Contoso Ltd Status = Inactive
Child Records
Contact 1 = Active Contact 2 = Active Contact 3 = Active
This creates a business inconsistency.
Ideally:
Account = Inactive ↓ All Related Contacts = Inactive
This ensures data integrity throughout the system.
Common Business Scenarios
Account Management
Deactivate related contacts.
Project Management
Deactivate project tasks.
Customer Service
Deactivate related service activities.
HR Systems
Deactivate employee-related records.
Membership Systems
Deactivate memberships and subscriptions.
Understanding the Process
Workflow:
Parent Record Deactivated ↓ Plugin Triggered ↓ Retrieve Child Records ↓ Loop Through Records ↓ Deactivate Child Records
The plug-in executes automatically whenever the parent record status changes.
Step 1: Create Plugin Project
Create a Class Library project in Visual Studio.
Install:
Microsoft.CrmSdk.CoreAssemblies
Required namespaces:
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
Step 2: Create Plugin Class
public class DeactivateChildRecords : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
}
}
This becomes the entry point for the plugin.
Step 3: Get Execution Context
IPluginExecutionContext context =
(IPluginExecutionContext)
serviceProvider.GetService(
typeof(IPluginExecutionContext));
Retrieve Organization Service:
IOrganizationServiceFactory factory =
(IOrganizationServiceFactory)
serviceProvider.GetService(
typeof(IOrganizationServiceFactory));
IOrganizationService service =
factory.CreateOrganizationService(
context.UserId);
Step 4: Check Status Change
Entity entity =
(Entity)context.InputParameters["EntityMoniker"];
Verify:
State = Inactive
Only proceed when the parent record is deactivated.
Step 5: Retrieve Child Records
Example: Account → Contacts
QueryExpression query =
new QueryExpression("contact");
query.Criteria.AddCondition(
"parentcustomerid",
ConditionOperator.Equal,
entity.Id);
EntityCollection contacts =
service.RetrieveMultiple(query);
The plugin retrieves all child records linked to the parent account.
Step 6: Deactivate Child Records
Loop through contacts:
foreach(Entity contact in contacts.Entities)
{
Entity updateContact =
new Entity("contact");
updateContact.Id = contact.Id;
updateContact["statecode"] =
new OptionSetValue(1);
updateContact["statuscode"] =
new OptionSetValue(2);
service.Update(updateContact);
}
Result:
All related contacts become inactive.
Complete Example
foreach(Entity child in contacts.Entities)
{
SetStateRequest request =
new SetStateRequest
{
EntityMoniker =
child.ToEntityReference(),
State =
new OptionSetValue(1),
Status =
new OptionSetValue(2)
};
service.Execute(request);
}
This ensures proper state transition handling.
Plugin Registration
Register the plugin using:
Plugin Registration Tool
Configuration:
Message
SetState
or
Update
Primary Entity
account
Stage
Post Operation
Execution Mode
Synchronous
or
Asynchronous
Real-World Example
Project Management System
Parent:
Project
Child:
Project Tasks
When a project is closed:
Project = Inactive
Plugin automatically:
Task 1 = Inactive Task 2 = Inactive Task 3 = Inactive
This prevents users from updating completed project tasks.
Advanced Scenario
Multiple Child Entities
Parent:
Account
Deactivate:
Contacts Cases Appointments Custom Records
Workflow:
Account Deactivated ↓ Plugin Executes ↓ Deactivate Contacts ↓ Deactivate Cases ↓ Deactivate Activities ↓ Deactivate Custom Records
Best Practices
Use Post Operation
Ensure parent record is already deactivated.
Use Tracing Service
Add logs for troubleshooting.
tracingService.Trace(
"Plugin Started");
Use Batch Processing
Improve performance for large datasets.
Handle Exceptions
Use try-catch blocks.
Avoid Infinite Loops
Check plugin depth.
if(context.Depth > 1)
return;
Use Asynchronous Execution
Recommended for large numbers of child records.
Benefits
- Better Data Integrity – Parent and child records remain synchronized.
- Improved Business Logic – Enforce business rules automatically.
- Reduced Manual Work – No need to deactivate records manually.
- Better User Experience – Users see consistent record states.
- Enterprise Scalability – Supports large business applications.
Common Use Cases
- CRM Account Management
- Project Management
- Customer Service
- HR Systems
- Membership Applications
Conclusion
Using a Dynamics 365 Plug-in to deactivate child records automatically is a powerful technique for maintaining data consistency and enforcing business rules.
By registering a plugin on parent record deactivation events, organizations can ensure that all related records remain synchronized, reducing manual effort and improving overall system reliability.
This approach is widely used across Dynamics 365 CRM and Dataverse implementations where parent-child relationships play a critical role in business processes.
```