How to Deactivate Child Records Using Plug-in in Dynamics 365

```html

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

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


Common Use Cases


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.

```