Cant map parent-child SOQL To Map<Id, Set>

apexmapparent-to-childsetsoql

Hi Im kind of stucked here, What Im trying to do is getting a Map which for each key (Id) will have a set of related objects.

Map<Id, Set<Id>> junctMap = new Map<Id, Set<Id>>([SELECT Id, (SELECT Id FROM Equipment_Maintenance_Items__r) FROM Case WHERE Id IN:idSet]);

Bu it keeps throwing me "Invalid initializer type List found for Map>: Expected a Map, with the same key and value types.

Do you know if my approach is valid or I'm doing it all wrong?

I would like to know, what am I doing wrong.

Best Answer

You can't do this with a single statement in Apex.

Queries always return a List<SObject>, and there is a constructor for the Map class that can take a List<SObject> and turn it into a Map<Id, SObject>. Anything that you want to do beyond that requires additional code.

Further, Apex will complain that there are too many child records if there are more than ~200 children for a given parent and you try to directly access the embedded List<SObject>. That'll try to kick off an internal call to queryMore(), and that's not allowed for fetching the child records.

The safest way to access the child records is with a nested loop.

for(Parent__c parentRec :parentList){
    system.debug(parentRec.Id);

    for(Child__c childRec :parentRec.Child_Relationship__r){
        system.debug(childRec.Id);
    }
}

So you'll need to build your Map<Id, Set<Id>> yourself, using the nested loop approach. You can:

  • Create a new Set<Id> in the outer loop (before the inner loop runs)
  • Add Ids to the set in the inner loop
  • myMap.put(parentId, childIdSet) in the outer loop (before or after the inner loop runs)

Having Set<Id> mySet = new Set<Id>(); inside of the outer loop ensures that your map will only store the child Ids for the given parent. If you'd define this set outside of all loops, you'd end up needing to do extra work to prevent cross-polination of child ids (and to avoid clearing out all ids).

Related Topic