Maps: adding more (related) sObjects than key values using PUTALL method
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) ...
So, basically, you would like to have a map of key-value pairs, where key is the AccountID, and the value is list of Contracts related to the Account? If so, first of all, rather than having Map < id, contract >, what you are really looking is Map < id, List < Contract > >.
Further on, you could store the list of id's - in the list. And only then use the list of ids to query the contracts and populate the map:
map<id, contract> accIDtoContract = new map<id, List<contract>>();
List<id> accIDs = new List<id>();
for( Usage_Data__c UD : Usage_Data_List ){
// Don't store AccountID in the list if it was already stored
if(accIDs.contains(UD.Account__c))
continue;
accIDs.add(UD.Account__c);
accIDtoContract(UD.Account__c, new List<Contract>());
}
List<contract> contracts = [SELECT ID, AccountID, random_field FROM Contract WHERE AccountID IN :accIDs]);
for(Contract c : contracts) {
accIDtoContract.get(c.AccountID).add(c);
}