breadcrumbDescription
Bedste fremgangsmåder for Apex
Følg disse bedste fremgangsmåder, når du implementerer Apex i dine prisprocedureplaner for at optimere ydeevnen og undgå uventede resultater.
Apex
Apex i procedureplaner kører i den samme Apex, så den centrale behandlingsenhedstimer er akkumuleret på tværs af alle handlinger. Vær opmærksom på styringsbegrænsninger, når du skriver kroglogik, især for transaktioner med mange linjevarer.
For aktuelle grænseværdier kan du se Udførelsesstyringer og begrænsninger i Apex Developer Guide.
Forespørg kun på de tags, du har brug for
Undgå at forespørge på brede tags på enhedsniveau som SalesTransactionItem, der returnerer hver attribut for hvert element. Anmod i stedet kun om de specifikke tags, som din hook-logik kræver.
Ikke anbefalet: Forespørg på brede tags
// BAD: Returns ALL attributes for every SalesTransactionItem
Map<String, Object> input = new Map<String, Object>{
'contextId' => contextId,
'tags' => new List<String>{ 'SalesTransactionItem' }
};
Map<String, Object> output = industriesContext.queryTags(input);
Anbefales: Forespørg kun på specifikke tags
// GOOD: Query only the specific tags (attributes) you need
Map<String, Object> input = new Map<String, Object>{
'contextId' => contextId,
'tags' => new List<String>{ 'LineItem', 'LineItemQuantity', 'ItemProductCode' }
};
Map<String, Object> output = industriesContext.queryTags(input);
Anbefales: Kombiner specifikke tags med leanerQueryTags
// BETTER: Combine specific tags with leanerQueryTags for maximum efficiency
Map<String, Object> input = new Map<String, Object>{
'contextId' => contextId,
'tags' => new List<String>{ 'LineItem', 'LineItem$DmlStatus',
'LineItemQuantity', 'ItemProductCode' }
};
Map<String, Object> output = industriesContext.leanerQueryTags(input);
Brug leanerQueryTags i stedet for queryTags
Klassen Context.IndustriesContext indeholder to metoder til at forespørge på kontekstdata. Brug leanerQueryTags, hvor det er muligt for bedre ydeevne.
queryTags (heavy) – Returnerer fulde kontekstnoder med indlejrede tag-værdikort og dataPath matrikser. Hver attribut er pakket ind i et kort med 6 felter (tagValue, dmlStatus, isDirty, isNodeLevelTag, tagPath, contextDataPathBuilder) pr. attribut pr. element. Alle attributter for tagget returneres, uanset hvad du har brug for.
leanerQueryTags (lightweight) – Returnerer en kompakt struktur med flade tagværdier og indeksbaserede registrerings-id-referencer. Tag-værdier har kun 3 felter (tagValue, recordIdIndexesForPath, isNodeLevelTag). Registrerings-id'er fjernes fra en delt recordsInfo. Noder refererer til dem efter indeks.
Følgende eksempel viser, hvordan du kalder leanerQueryTags og behandler dets output.
String contextId = request.ctxInstanceId;
Context.IndustriesContext industriesContext = new Context.IndustriesContext();
Map<String, Object> input = new Map<String, Object>{
'contextId' => contextId,
'tags' => new List<String>{ 'LineItem', 'ItemProductCode', 'LineItemQuantity' }
};
Map<String, Object> output = industriesContext.leanerQueryTags(input);
// Access the leaner result structure
Map<String, Object> queryResult = (Map<String, Object>)
output.get('leanerQueryTagResult');
List<Object> recordsInfo = (List<Object>) output.get('recordsInfo');
List<Object> lineItems = (List<Object>) queryResult.get('LineItem');
// Iterate over tag values — each tag is flat
List<Object> productCodes = (List<Object>) queryResult.get('ItemProductCode');
for (Object obj : productCodes) {
Map<String, Object> tagNode = (Map<String, Object>) obj;
String productCode = (String) tagNode.get('tagValue');
List<Integer> indexes = (List<Integer>) tagNode.get('recordIdIndexesForPath');
// recordsInfo entries are maps with 'recordId' and 'dmlStatusOrdinal'
String itemId = (String) ((Map<String, Object>)
recordsInfo.get(indexes[1])).get('recordId');
}
leanerQueryTags-outputstrukturen ser sådan ud:
{
"isSuccess": true,
"contextId": "...",
"leanerQueryTagResult": {
"LineItem": [
{ "recordIdIndexesForPath": [0, 1], "tagValue": "0QLVW000001LxvN4AS", "isNodeLevelTag": false },
{ "recordIdIndexesForPath": [0, 2], "tagValue": "0QLVW000001Lxus4AC", "isNodeLevelTag": false }
],
"ItemProductCode": [
{ "recordIdIndexesForPath": [0, 1], "tagValue": "PROD-001", "isNodeLevelTag": false },
{ "recordIdIndexesForPath": [0, 2], "tagValue": "PROD-002", "isNodeLevelTag": false }
]
},
"recordsInfo": [
{ "recordId": "0Q0VW0000011qC50AI", "dmlStatusOrdinal": null },
{ "recordId": "0QLVW000001LxvN4AS", "dmlStatusOrdinal": null },
{ "recordId": "0QLVW000001Lxus4AC", "dmlStatusOrdinal": null }
]
}
Migrer fra queryTags til leanerQueryTags
Når du migrerer eksisterende kroge fra queryTags til leanerQueryTags, skal du anvende disse nøgletransformationer.
Input: Brug individuelle tags i stedet for brede tags
// Before (queryTags — broad tag):
Map<String, Object> input = new Map<String, Object>{
'contextId' => contextId,
'tags' => new List<String>{ 'SalesTransactionItem' }
};
Map<String, Object> output = industriesContext.queryTags(input);
// After (leanerQueryTags — specific tags):
Map<String, Object> input = new Map<String, Object>{
'contextId' => contextId,
'tags' => new List<String>{ 'LineItem', 'LineItem$DmlStatus',
'ItemProductCode', 'LineItemQuantity' }
};
Map<String, Object> output = industriesContext.leanerQueryTags(input);
Output: Forskellig nøgle på topniveau
// Before:
Map<String, Object> queryResult = (Map<String, Object>) output.get('queryResult');
List<Object> items = (List<Object>) queryResult.get('SalesTransactionItem');
// After:
Map<String, Object> queryResult = (Map<String, Object>)
output.get('leanerQueryTagResult');
List<Object> recordsInfo = (List<Object>) output.get('recordsInfo');
List<Object> lineItems = (List<Object>) queryResult.get('LineItem');
Nodeadgang: Flade værdier i stedet for indlejrede kort
// Before (queryTags — nested map extraction):
for (Object itemObj : items) {
Map<String, Object> itemNode = (Map<String, Object>) itemObj;
Map<String, Object> tagValueMap = (Map<String, Object>) itemNode.get('tagValue');
String productCode = (String) ((Map<String, Object>)
tagValueMap.get('ItemProductCode')).get('tagValue');
Decimal quantity = (Decimal) ((Map<String, Object>)
tagValueMap.get('LineItemQuantity')).get('tagValue');
}
// After (leanerQueryTags — flat value, iterated per tag):
List<Object> productCodes = (List<Object>) queryResult.get('ItemProductCode');
List<Object> recordsInfo = (List<Object>) output.get('recordsInfo');
for (Object obj : productCodes) {
Map<String, Object> tagNode = (Map<String, Object>) obj;
String productCode = (String) tagNode.get('tagValue');
List<Integer> indexes = (List<Integer>) tagNode.get('recordIdIndexesForPath');
String itemId = (String) ((Map<String, Object>)
recordsInfo.get(indexes[1])).get('recordId');
}
Registrerings-id'er: Indeksreferencer i stedet for dataPath
// Before (queryTags):
List<Object> dataPath = (List<Object>) itemNode.get('dataPath');
// dataPath = ['contextId', 'txnId', 'itemId'] — 3 elements, first is contextId
dataPath.remove(0);
String transactionId = (String) dataPath.get(0);
// After (leanerQueryTags):
List<Object> recordsInfo = (List<Object>) output.get('recordsInfo');
List<Integer> indexes = (List<Integer>) tagNode.get('recordIdIndexesForPath');
String transactionId = (String) ((Map<String, Object>)
recordsInfo.get(indexes[0])).get('recordId');
String itemId = (String) ((Map<String, Object>)
recordsInfo.get(indexes[1])).get('recordId');
Brug tagIdIndexMap-mønsteret
Når du behandler flere tags i en enkelt løkke, skal du bruge en tagIdIndexMap til at tilknytte hvert tagnavn til dets position i recordIdIndexesForPath. Dette giver dig mulighed for at udtrække id'er korrekt på hvert hierarkiniveau:
Map<String, Integer> tagIdIndexMap = new Map<String, Integer>{
'LineItem' => 1, // item-level tag, ID at index 1
'LineItem$DmlStatus' => 1, // item-level tag, ID at index 1
'LineItemQuantity' => 1, // item-level tag, ID at index 1
'BusinessUnit__c' => 0, // transaction-level tag, ID at index 0
'Contract' => 0 // transaction-level tag, ID at index 0
};
- Indeks 0 = transaktionsniveau (stien har et element: [
txnId]) - Indeks 1 = elementniveau (stien har to elementer: [
txnId,itemId]) - Indeks 2 = detaljeniveau (stien har tre elementer: [
txnId,itemId,detailId])
Filtrer slettede elementer
Ignorer slettede elementer ved starten af din gentagelsesløbe for at undgå unødvendig behandling. Anmod om LineItem$DmlStatus som et separat tag i din forespørgsel:
private static final String DML_DELETED = 'DELETED';
for (Map<String, Object> item : salesTransactionInstance.salesTransactionItems) {
String dmlStatus = (String) item.get('LineItem$DmlStatus');
if (dmlStatus == DML_DELETED) {
continue; // Skip deleted items
}
// Process active items...
}
Læs $DmlStatus som et separat tag
Når der forespørges på specifikke tags (den anbefalede tilgang), integreres DML-statussen ikke i tag-metadataene. Du skal anmode om LineItem$DmlStatus som et separat tag. Dette gælder både for queryTags og leanerQueryTags.
// Add LineItem$DmlStatus to your tags list
'tags' => new List<String>{ 'LineItem', 'LineItem$DmlStatus', 'ItemProductCode' }
// Access it like any other tag in the result
Map<String, Object> dmlNode = (Map<String, Object>) dmlStatusValues.get(i);
String dmlStatus = String.valueOf(dmlNode.get('tagValue'));
