Apex Salesforce: Count the associated child records to parent record

 Below is the Apex class to count all child records associated with a parent record, ensuring:

Bulk-safe operations
Optimized SOQL queries (avoiding loops inside queries)
Efficient use of Maps to reduce processing time

🔹 How This Code is Optimized

  1. Uses Maps for O(1) Lookup:

    • Stores parent IDs with a default count of 0 to avoid missing entries.

  2. Avoids SOQL Queries in Loops:

    • Uses a single SOQL query with GROUP BY to count child records efficiently.

  3. Bulk-Safe & Scalable:

    • Accepts a list of parent IDs to handle multiple records in a single execution.

  4. Dynamic Query Construction:

    • Works with any parent-child object pair by passing object names dynamically.

  5. Exception Handling:

    • Validates input parameters to prevent runtime errors.

ContactTrigger

trigger ContactTrigger on Contact (after insert, after update, after delete, after undelete) {
    // Set to store affected Account IDs
    Set<Id> accountIds = new Set<Id>();

    // Capture Account IDs from Trigger context
    if (Trigger.isInsert || Trigger.isUpdate || Trigger.isUndelete) {
        for (Contact con : Trigger.new) {
            if (con.AccountId != null) {
                accountIds.add(con.AccountId);
            }
        }
    }
    
    if (Trigger.isUpdate || Trigger.isDelete) {
        for (Contact con : Trigger.old) {
            if (con.AccountId != null) {
                accountIds.add(con.AccountId);
            }
        }
    }

    // Ensure Account IDs are not empty
    if (!accountIds.isEmpty()) {
        ContactTriggerHelper.updateContactCounts(accountIds);
    }
}


ContactTriggerHandler


public with sharing class ContactTriggerHelper {
    
    /**
     * Updates the Contact Count field on Account records
     * @param accountIds Set of Account record IDs to update
     */
    public static void updateContactCounts(Set<Id> accountIds) {
        if (accountIds == null || accountIds.isEmpty()) {
            return; // Exit if no Account IDs
        }

        // Map to store Account ID -> Contact Count
        Map<Id, Integer> accountContactCountMap = new Map<Id, Integer>();

        // Initialize all Account IDs with a count of 0
        for (Id accountId : accountIds) {
            accountContactCountMap.put(accountId, 0);
        }

        // Query all Contacts related to the given Accounts
        List<Contact> contacts = [
            SELECT Id, AccountId 
            FROM Contact 
            WHERE AccountId IN :accountIds
        ];

        // Count Contacts for each Account
        for (Contact contact : contacts) {
            if (accountContactCountMap.containsKey(contact.AccountId)) {
                accountContactCountMap.put(contact.AccountId, accountContactCountMap.get(contact.AccountId) + 1);
            }
        }

        // Prepare Account records for update
        List<Account> accountsToUpdate = new List<Account>();
        for (Id accountId : accountContactCountMap.keySet()) {
            accountsToUpdate.add(new Account(Id = accountId, Contact_Count__c = accountContactCountMap.get(accountId)));
        }

        // Perform DML update (bulk-safe)
        if (!accountsToUpdate.isEmpty()) {
            update accountsToUpdate;
        }
    }
}

Comments

Popular posts from this blog

Object Relationship