[SalesForce] Maps: adding more (related) sObjects than key values using PUTALL method

Here's the scenario: you've loaded a bunch of account IDs as keys into your map. But now, instead of loading account records as the sObject values, you're going to load a related object, such as Contracts. Here's my code to illustrate:

map<id, contract> accIDtoContract = new map<id, contract>();

    for( Usage_Data__c UD : Usage_Data_List ){
            accIDtoContract.put(UD.Account__c, NULL);                      
    }

    accIDtoContract.remove(null); 

    accIDtoContract.putAll([SELECT ID, random_field
                                   FROM Contract WHERE AccountID IN :accIDtoContract.keySet()]);

First off, am I correct in assuming that the contract records will populate by matching their Account ID lookup field to the keys in the map?

Next, how does PUTALL handle it when you try to add mutiple values that relate to the same key (per my example, when the SOQL query in the PUTALL call returns more than one contract per account ID)?

Thanks for your help guys

Best Answer

PutAll only works on the ID field of an SObject. It is syntatic sugar for:

for(SObject record: someList)
    someMap.put(record.Id, record);

To use any other type of mapping, you would have to make your own for loop.

Such a for loop would look like:

Map<Id, Contract[0]> someMap = new Map<id, contract[0]>();

... load account ids here ...

for(Contract record: [SELECT Id, AccountId, random_field FROM Contract WHERE AccountId IN :someMap.keyset()]) {
    if(someMap.get(record.AccountId) == null) {
        someMap.put(record.AccountId, new Contract[0]);
    }
    someMap.get(record.AccountId).add(record);
}

In your specific case, I might consider using a subquery:

someMap.putAll([SELECT Id, (SELECT Id, random_field FROM Contracts) FROM Account WHERE Id IN :someMap.keySet()]);

You can access a list of contracts via:

for(Contract record: someMap.get(accountId).Contracts) ...
Related Topic