Search code examples
salesforceapexapex-codesoql

Get list of parent records from multilevel SOQL query


I'm trying to combine 3 separate SOQL queries into one, but still end up with 3 separate lists for ease of use and readability later.

List<Object__c> objectList = [SELECT Name, Id, Parent_Object__r.Name, Parent_Object__r.Id,
                                   (SELECT Name, Id FROM Child_Objects__r)
                                FROM Object__c];

I know I can get a list of child objects thus:

List<Child_Object__c> childObjectList = new List<Child_Object__c>();
for(Object__c object : objectList){
   childObjectList.addAll(object.Child_Objects__r);
}

How would I go about adding the Parent_Object__c records to their own list? I'm assuming a map could be used to deal with duplicates, but how do I get this Parent_Object__c data into that map?


Solution

  • You are basically there.

    All lookup fields are available in your example as object.Parent_Object__r. Use a Set to natively avoid duplicates. No deduping required on your part!

    Set<Parent_Object__c> parentObjectSet = new Set<Parent_Object__c>();
    List<Child_Object__c> childObjectList = new List<Child_Object__c>();
    for(Object__c object : objectList){
      childObjectList.addAll(object.Child_Objects__r);
      parentObjectSet.add(object.Parent_Object__r);
    }
    

    Edit:

    As per @eyescream (trust him!) you are indeed better off with a map to avoid duplicates.

    So the above code would just be slightly different:

    Map<Id, Parent_Object__c> parentObjectMap = new Map<Id, Parent_Object__c>();
    List<Child_Object__c> childObjectList = new List<Child_Object__c>();
    for(Object__c object : objectList){
      childObjectList.addAll(object.Child_Objects__r);
      if (object.Parent_Object__r != null) {
        parentObjectMap.put(object.Parent_Object__r.Id, object.Parent_Object__r);
      }
    }