Salesforce触发器开发:阻止删除含主联系人的账户及统计主联系人数量
Salesforce 触发器修复与主联系人统计方案
1. 修复阻止删除存在主联系人的账户触发器
原触发器存在以下问题:
- 双重循环冗余,无需嵌套遍历
trigger.old与查询结果 - 未筛选
primary_contact__c = true的联系人,仅判断联系人存在就阻止删除 - 错误提示信息不够清晰
修复后的触发器代码:
trigger AccountPreventDelete on Account (before delete) { // 查询待删除账户及其关联的主联系人(primary_contact__c为true) Map<Id, Account> accountWithPrimaryContacts = new Map<Id, Account>( [SELECT Id, (SELECT Id FROM Contacts WHERE primary_contact__c = true) FROM Account WHERE Id IN :Trigger.old] ); // 遍历每个待删除账户 for (Account acc : Trigger.old) { Account accWithContacts = accountWithPrimaryContacts.get(acc.Id); // 检查是否存在关联的主联系人 if (accWithContacts != null && accWithContacts.Contacts.size() > 0) { acc.addError('无法删除该账户,因为存在标记为「主要联系人」的关联联系人记录'); } } }
代码说明:
- 使用
Map存储查询结果,通过ID快速匹配待删除账户,避免冗余循环 - SOQL中直接筛选
primary_contact__c = true的联系人,减少不必要的数据查询 - 错误提示明确说明阻止删除的原因,提升用户操作体验
2. 统计指定账户的主联系人数量
提供两种实用方案:
方法1:直接SOQL查询(Apex代码中使用)
如果仅需在代码中临时统计,可使用如下查询:
// 替换为目标账户ID Id targetAccountId = '001XXXXXXXXXXXX'; Integer primaryContactCount = [ SELECT COUNT() FROM Contact WHERE AccountId = :targetAccountId AND primary_contact__c = true ]; System.debug('主联系人数量:' + primaryContactCount);
方法2:触发器自动更新账户字段(实时展示推荐)
若需在账户页面实时显示主联系人数量,先创建数字类型自定义字段(例如Primary_Contact_Count__c),再编写触发器自动更新:
trigger ContactUpdateAccountPrimaryCount on Contact (after insert, after update, after delete, after undelete) { Set<Id> accountIds = new Set<Id>(); // 收集关联的账户ID if (Trigger.isInsert || Trigger.isUpdate || Trigger.isUndelete) { for (Contact con : Trigger.new) { if (con.AccountId != null) { accountIds.add(con.AccountId); } } } if (Trigger.isDelete) { for (Contact con : Trigger.old) { if (con.AccountId != null) { accountIds.add(con.AccountId); } } } // 避免空查询 if (accountIds.isEmpty()) return; // 查询每个账户的主联系人数量 List<AggregateResult> results = [ SELECT AccountId, COUNT(Id) cnt FROM Contact WHERE AccountId IN :accountIds AND primary_contact__c = true GROUP BY AccountId ]; // 更新账户的统计字段 List<Account> accountsToUpdate = new List<Account>(); for (AggregateResult ar : results) { accountsToUpdate.add(new Account( Id = (Id)ar.get('AccountId'), Primary_Contact_Count__c = (Integer)ar.get('cnt') )); } // 处理没有主联系人的账户,将统计字段设为0 Set<Id> updatedAccountIds = new Set<Id>(); for (Account acc : accountsToUpdate) { updatedAccountIds.add(acc.Id); } for (Id accId : accountIds) { if (!updatedAccountIds.contains(accId)) { accountsToUpdate.add(new Account( Id = accId, Primary_Contact_Count__c = 0 )); } } update accountsToUpdate; }
代码说明:
- 覆盖联系人增删改查全场景,确保统计数据实时准确
- 自动处理无主联系人的账户,将统计字段设为0,避免空值
内容的提问来源于stack exchange,提问作者Mohsin
相关产品推荐
相关产品推荐

