Salesforce 如何将soql计数的聚合结果存储在列表中
我正在统计一个联系人拥有的相关帐户的数量。 此号码应存储在“联系人”上的自定义字段中,并应在每次添加或删除关系时更新,从而通过触发代码进行更新。 为了计算当前关系的数量,我希望将以下查询的结果存储在一个列表上,之后我希望循环该列表以更新联系人记录:Salesforce 如何将soql计数的聚合结果存储在列表中,salesforce,apex,Salesforce,Apex,我正在统计一个联系人拥有的相关帐户的数量。 此号码应存储在“联系人”上的自定义字段中,并应在每次添加或删除关系时更新,从而通过触发代码进行更新。 为了计算当前关系的数量,我希望将以下查询的结果存储在一个列表上,之后我希望循环该列表以更新联系人记录: List acr=新列表([从AccountContactRelation中选择ContactId,Count(Id),其中ContactId位于:ContactId和Active__c=按ContactId分组]); 但是,这会引发一个错误: “
List acr=新列表([从AccountContactRelation中选择ContactId,Count(Id),其中ContactId位于:ContactId和Active__c=按ContactId分组]);
但是,这会引发一个错误:
“System.ListException:索引0处Id为空的行”
如何建立此列表以便进一步处理
亲切问候,,
Stefan问得好
一般来说,在Apex中运行SOQL会产生一个值,该值具体化为单个SObject
类或列表
(通用SObject,或与FROM
子句类型匹配的确切SObject类型)。这正是你想要做的
但是,在Apex中运行聚合SOQL时,会出现一些不同的情况
首先,如果聚合结果是一个简单的数值,那么您可能会得到一个返回类型Integer
Integer myAggregate = [SELECT Count() FROM Account WHERE Type = 'Prospect'];
System.debug(myAggregate); //output: 36
但是,对于您正在执行的操作,聚合值有一种特殊的泛型类型,称为AggregateResult
。一个AggregateResult
实例实际上就像一个映射,其中每个字段都通过其键进行访问,并使用get('fieldName')
访问器进行检索。您的查询将在列表中返回此信息。下面是一个可能的流程,您可以使用它创建要更新的联系人列表
List<Contact> contactsToUpdate = new List<Contact>();
List<AggregateResult> resultList = [SELECT ContactId, Count(Id) relationCount
FROM AccountContactRelation
WHERE ContactId IN :contactIds
AND Active__c = true GROUP by ContactId];
for (AggregateResult ar: resultList) {
//assign to contacts here.
Contact contactToUpdate = new Contact();
contactToUpdate.Id = (Id) ar.get('ContactId');
contactToUpdate.Custom_Count_Field__c = (Integer) ar.get('relationCount');
contactsToUpdate.add(contactToUpdate);
}
// always perform DML outside of loops in Apex
update contactsToUpdate; //you may want to use Database.update()
List contactsToUpdate=new List();
List resultList=[选择联系人Id,计数(Id)关系计数]
从会计联系关系
ContactId所在位置:ContactId
和Active_u_c=通过ContactId的真实组];
for(AggregateResult ar:resultList){
//在此处指定联系人。
Contact contactToUpdate=新联系人();
contactToUpdate.Id=(Id)ar.get('ContactId');
contactToUpdate.Custom_Count_Field__c=(整数)ar.get('relationCount');
contactsToUpdate.add(contactToUpdate);
}
//始终在Apex中的循环外执行DML
更新联系人更新//您可能需要使用Database.update()
有几件事需要注意
- 在执行内联SOQL时,不需要调用
SObject
或List
构造函数。这是含蓄的
- 在聚合查询中,请注意别名的使用。虽然别名在SOQL中基本上是不相关的(在我看来),但在这里它们是必不可少的,否则会为所有聚合值分配一个通用键,这些聚合值称为
expr0
,expr1
,等等。。。。不要这样对自己
AggregateResult
的字段一般都被键入为Object
。您需要强制转换它们以匹配基础SObject字段类型。在我的例子中,我假设您的自定义字段定义为数字字段
List<Contact> contactsToUpdate = new List<Contact>();
List<AggregateResult> resultList = [SELECT ContactId, Count(Id) relationCount
FROM AccountContactRelation
WHERE ContactId IN :contactIds
AND Active__c = true GROUP by ContactId];
for (AggregateResult ar: resultList) {
//assign to contacts here.
Contact contactToUpdate = new Contact();
contactToUpdate.Id = (Id) ar.get('ContactId');
contactToUpdate.Custom_Count_Field__c = (Integer) ar.get('relationCount');
contactsToUpdate.add(contactToUpdate);
}
// always perform DML outside of loops in Apex
update contactsToUpdate; //you may want to use Database.update()