I have a question about APEX programming practices. My problem: I'm moving a SOQL query out of a for loop in an algorithm to allow for more processing per execution context. The SOQL queried PricebookEntry with parameters Pricebook, CurrencyIsoCode, and Product2ID, targeting a set of products of size 200, and returns a list of PricebookEntries (theoretically should be a list of 1).
To accommodate this with only 2 SOQL queries instead of N = loop length, I've built a map of maps of maps of lists, I populate it a single time (on first reference), then I traverse it from within the for loop, given my parameters.
What is the consensus on using collections this way?
public static Map<ID, Map<string, Map<ID, List<PricebookEntry>>>> pricebookToCurrencyToProductIdsToPricebookEntryList
{
get
{
if (pricebookToCurrencyToProductIdsToPricebookEntryList == null)
{
pricebookToCurrencyToProductIdsToPricebookEntryList = new Map<ID, Map<string, Map<ID, List<PricebookEntry>>>>();
Set<Legacy_Mapping__c> mappedSubscriptionProducts = new Set<Legacy_Mapping__c>([SELECT Subscription_Part__c from Legacy_Mapping__c]);
Set<ID> distinctProducts = new Set<ID>();
if (mappedSubscriptionProducts != null)
{
if (mappedSubscriptionProducts.size() > 0)
{
for (Legacy_Mapping__c singleMapping : mappedSubscriptionProducts)
{
distinctProducts.add(singleMapping.Subscription_Part__c);
}
List<PricebookEntry> allPricebookEntries = [SELECT Id, CurrencyIsoCode, Pricebook2Id, Product2Id FROM PricebookEntry
WHERE Product2Id in :distinctProducts and
IsActive = true];
if (allPricebookEntries != null)
{
if (allPricebookEntries.size() > 0)
{
for (PricebookEntry pbEntry : allPricebookEntries)
{
if (pricebookToCurrencyToProductIdsToPricebookEntryList.containsKey(pbEntry.Pricebook2Id))
{
Map<string, Map<ID, List<PricebookEntry>>> currencyToProductIdsToPricebookEntryList
= pricebookToCurrencyToProductIdsToPricebookEntryList.get(pbEntry.Pricebook2Id);
if (currencyToProductIdsToPricebookEntryList != null && currencyToProductIdsToPricebookEntryList.containsKey(pbEntry.CurrencyIsoCode))
{
Map<ID, List<PricebookEntry>> productIdsToPricebookEntryList
= currencyToProductIdsToPricebookEntryList.get(pbEntry.CurrencyIsoCode);
if (productIdsToPricebookEntryList != null && productIdsToPricebookEntryList.containsKey(pbEntry.Product2Id))
{
List<PricebookEntry> pricebookEntryList = productIdsToPricebookEntryList.get(pbEntry.Product2Id);
if (pricebookEntryList != null)
{
pricebookEntryList.add(pbEntry);
}
else
{
pricebookEntryList = new List<PricebookEntry>();
pricebookEntryList.add(pbEntry);
}
//put back
productIdsToPricebookEntryList.put(pbEntry.Product2Id, pricebookEntryList);
currencyToProductIdsToPricebookEntryList.put(pbEntry.CurrencyIsoCode, productIdsToPricebookEntryList);
pricebookToCurrencyToProductIdsToPricebookEntryList.put(pbEntry.Pricebook2Id, currencyToProductIdsToPricebookEntryList);
}
else //add productID map w just this entry
{
List<PricebookEntry> pbList = new List<PricebookEntry>();
pbList.add(pbEntry);
//put back
productIdsToPricebookEntryList.put(pbEntry.Product2Id, pbList);
currencyToProductIdsToPricebookEntryList.put(pbEntry.CurrencyIsoCode, productIdsToPricebookEntryList);
pricebookToCurrencyToProductIdsToPricebookEntryList.put(pbEntry.Pricebook2Id, currencyToProductIdsToPricebookEntryList);
}
}
else //add currency map w just this entry
{
List<PricebookEntry> pbList = new List<PricebookEntry>();
pbList.add(pbEntry);
//put back
Map<ID, List<PricebookEntry>> productIdsToPricebookEntryList = new Map<ID, List<PricebookEntry>>();
productIdsToPricebookEntryList.put(pbEntry.Product2Id, pbList);
currencyToProductIdsToPricebookEntryList.put(pbEntry.CurrencyIsoCode, productIdsToPricebookEntryList);
pricebookToCurrencyToProductIdsToPricebookEntryList.put(pbEntry.Pricebook2Id, currencyToProductIdsToPricebookEntryList);
}
}
else //add pricebook map w just this entry
{
List<PricebookEntry> pbList = new List<PricebookEntry>();
pbList.add(pbEntry);
Map<ID, List<PricebookEntry>> productIdsToPricebookEntryList = new Map<ID, List<PricebookEntry>>();
productIdsToPricebookEntryList.put(pbEntry.Product2Id, pbList);
Map<string, Map<ID, List<PricebookEntry>>> currencyToProductIdsToPricebookEntryList
= new Map<string, Map<ID, List<PricebookEntry>>>();
currencyToProductIdsToPricebookEntryList.put(pbEntry.CurrencyIsoCode, productIdsToPricebookEntryList);
//put
pricebookToCurrencyToProductIdsToPricebookEntryList.put(pbEntry.Pricebook2Id, currencyToProductIdsToPricebookEntryList);
}
}
}
}
}
}
}
return pricebookToCurrencyToProductIdsToPricebookEntryList;
}
private set;
}