我需要收集有关每种记录类型可用的选项列表值的信息。我知道这可以使用describeLayout 或readMetadata API 来实现。但是当我尝试为大型自定义对象收集这些信息时,麻烦就发生了。 SalesForce API 返回一个记录类型及其所有可用选项列表值。
<recordTypeMappings>
<name>Record1</name>
<picklistsForRecordType>
<picklistName>Picklist1</picklistName>
<picklistValues>
...
</picklistValues>
</picklistsForRecordType>
<picklistsForRecordType>
<picklistName>Picklist2</picklistName>
<picklistValues>
...
</picklistValues>
</picklistsForRecordType>
</recordTypeMappings>
<recordTypeMappings>
<name>Record2</name>
<picklistsForRecordType>
<picklistName>Picklist1</picklistName>
<picklistValues>
...
</picklistValues>
</picklistsForRecordType>
<picklistsForRecordType>
<picklistName>Picklist2</picklistName>
<picklistValues>
...
</picklistValues>
</picklistsForRecordType>
</recordTypeMappings>
这意味着如果我有一个大对象(其中包括 200 个选项列表和 100 个记录类型),我将获得 200*100=20,000 个选项列表记录。它使得 API 响应非常大,高达 80MB。这是非常低效的,如果所有记录类型的选项列表值保持相同,它们仍将包含在 API 响应中的每个记录中。
这个想法是获取唯一的选项列表值集,然后只在其中包含记录 ID,因此每个记录类型都不会重复相同的选项列表。
<recordTypeMappings>
<name>Record1, Record2</name>
<picklistsForRecordType>
<picklistName>Picklist1</picklistName>
<picklistValues>
...Values which are the same for Record1 and Record2...
</picklistValues>
</picklistsForRecordType>
<picklistsForRecordType>
<picklistName>Picklist2</picklistName>
<picklistValues>
...Values which are the same for Record1 and Record2...
</picklistValues>
</picklistsForRecordType>
</recordTypeMappings>
这将减少响应大小。 Apex 有办法做到这一点吗?我在 API 中进行了搜索,但没有找到合适的东西。 Apex 似乎是更好的解决方案,因为所有处理都将在 Salesforce 端进行。
感谢您的帮助。
要过滤掉重复项并仅获取唯一值,请尝试在a Set中捕获选项列表值的集合。例如,这里有一个函数,它接受字段列表(在本例中它是选项列表字段的列表)并返回一组唯一的选项列表值。
// Given a list of picklist fields, return a set of unique picklist values
Set<Schema.PicklistEntry> getUniquePickListValues(List<Schema.DescribeFieldResult> pickListFields) {
Set<Schema.PicklistEntry> uniquePicklistValues = Set<Schema.PicklistEntry>();
for(Schema.DescribeFieldResult pickList : pickListFields){
List<Schema.PicklistEntry> pickListValues = pickList.getDescribe().getPicklistValues();
for(Schema.PicklistEntry entry : pickListValues){
uniquePicklistValues.add(entry);
}
}
return uniquePicklistValues;
}
我知道使用嵌套循环效率低下,但我不知道是否有更好的方法将对象列表合并到 Set 中。
希望这有帮助。
如果您想根据记录类型检索选项列表值,请在此处查看我的解决方案, https://salesforce.stackexchange.com/questions/103837/how-do-i-get-the-intersection-of-recordtype-and-picklist-values-inside-apex/202519#202519
它使用 REST API 调用,但响应将类似于 getdescribe 结果加上记录类型信息。
以下是解决性能和体积问题的方法。
面临的挑战是收集具有大量记录类型和选项列表的大型自定义对象的所有记录类型的可用选项列表值。 首先,我没有找到任何方法可以直接在 Apex 中执行此操作,我使用了 API 调用。
当我们通过describeSObject调用收到自定义对象描述时(https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_calls_describesobject.htm),我们获得所有选项列表值和记录类型值。我们没有得到的是每个记录类型可用的特定选项列表值。为此,我们需要执行describeLayout请求(https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_calls_describelayout.htm)。使用来自describeSObject 的信息,我们可以尝试预测describeLayout 响应有多大。
例如,如果我们有 500 个选项列表值和 20 个记录类型,describeLayout 的总响应将最多有 500*20=10,000 个选项列表值(因为 describeLayout 返回可用于每种记录类型的所有选项列表值)。然后我们需要估算 XML 响应的大小,因为 Salesforce API 的响应限制为 5mb。检查响应后,我发现为了匹配 5mb 限制,我们需要满足每个描述布局请求少于 30,000 个选项列表值的要求。
解决方案是将这个大型调用按记录类型分成几个较小的调用,因此我们检索一些记录类型的所有选项列表值,然后对其他记录类型重复。
最多需要 24 个 API 请求才能从 SalesForce API 检索 70MB 的数据,由于响应大小限制,通过一次 API 调用不可能实现这一点。