function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Phuc Nguyen 18Phuc Nguyen 18 

Get queries outside for loop

Happy New Year everyone.
Need some assistance with my class.  Trying to get the SOQL queries outside the for loop if possible.  But in teh query I am using the Id as a filter.  Any thoughts? 
if( Trigger.isInsert ){
            List<Id> docIds = new List<Id>();
            List<String> parentIds = new List<String>();

            for( Attachment__c record : ( List<Attachment__c> ) Trigger.new ){
                Id docId = record.ContentDocumentId__c;
                    parentId = record.Parent_ID__c ;
                    Id recId = Id.valueOf(record.Parent_ID__c ); 
                    String parentObjectType = String.valueOf( recId.getSObjectType());
                        if( parentObjectType == 'Activity__c' ){
                           list<Activity__c> actparentId = [Select id,Project__r.Cust__c  from Activity__c WHERE Id =: parentId];   
                           for(Activity__c act :actparentId){
                                parentId = act.Project__r.Cust__c;
                            }
                        }
                        
                        if( parentObjectType == 'Project__c' ){
                           list<Project__c> projparentId = [Select Cust__c from Project__c WHERE Id =: parentId];   
                           for(Project__c proj :projparentId){
                                parentId = proj.Cust__c;
                            }
                        }
                        
                        if( docId != null ){    
                            docIds.add( docId );
                        }
            }

            List<ContentDocumentLink> linkList = [ SELECT Id, ContentDocumentId, LinkedEntityId FROM ContentDocumentLink WHERE ContentDocumentId IN: docIds ];
            if( !linkList.isEmpty() ){
                for( ContentDocumentLink link : linkList ){
                    List<ContentDocumentLink> links = this.linkMap.containsKey( link.ContentDocumentId )
                        ? this.linkMap.get( link.ContentDocumentId ) : new List<ContentDocumentLink>();
                    links.add( link );
                    this.linkMap.put( link.ContentDocumentId, links );
                }
            }
        
        }

 
Best Answer chosen by Phuc Nguyen 18
SUCHARITA MONDALSUCHARITA MONDAL

Hi Phuc,

Please check with the below code:

 

Set<Id> attParentIds = new Set<Id>();
            
            for( Attachment__c record : ( List<Attachment__c> ) Trigger.new ){
                 String parentObjectType = String.valueOf( recId.getSObjectType());
                 if( parentObjectType == 'Activity__c' )
                    attParentIds.add(record.Parent_ID__c) ;  //getting parentIds based on Object type
            }

            Map<Id,Activity__c> mapAttParentId = new Map<Id,Activity__c>([SELECT Id,Project__r.Cust__c  from Activity__c 
                                                                                                                    WHERE Id IN : attParentIds]);    // adding Map for storing results

        


            for(Attachment__c record : ( List<Attachment__c> ) Trigger.new){
                Id docId = record.ContentDocumentId__c;
                if(mapAttParentId.containsKey(record.Parent_ID__c)) {. // using Map for inside loop instead of SOQL
                    for(Activity__c act : mapAttParentId.values()){
                        //fetch Activity__c details
                    }
                }
            }



Hope this helps!
Thanks,
Sucharita

All Answers

SUCHARITA MONDALSUCHARITA MONDAL

Hi Phuc,

Please check with the below code:

 

Set<Id> attParentIds = new Set<Id>();
            
            for( Attachment__c record : ( List<Attachment__c> ) Trigger.new ){
                 String parentObjectType = String.valueOf( recId.getSObjectType());
                 if( parentObjectType == 'Activity__c' )
                    attParentIds.add(record.Parent_ID__c) ;  //getting parentIds based on Object type
            }

            Map<Id,Activity__c> mapAttParentId = new Map<Id,Activity__c>([SELECT Id,Project__r.Cust__c  from Activity__c 
                                                                                                                    WHERE Id IN : attParentIds]);    // adding Map for storing results

        


            for(Attachment__c record : ( List<Attachment__c> ) Trigger.new){
                Id docId = record.ContentDocumentId__c;
                if(mapAttParentId.containsKey(record.Parent_ID__c)) {. // using Map for inside loop instead of SOQL
                    for(Activity__c act : mapAttParentId.values()){
                        //fetch Activity__c details
                    }
                }
            }



Hope this helps!
Thanks,
Sucharita

This was selected as the best answer
Phuc Nguyen 18Phuc Nguyen 18
Thanks for the reply Sucharita,
I am trying this same approach but the issue I am seeing is that I need to be able to differentiate if the attachment is from an Activty or Project. Do I need 2 maps and then have to iterate threw both of them?
 
Phuc Nguyen 18Phuc Nguyen 18
And to confirm.  the syntax would be 
for(Activity__c act : mapAttParentId.values()){
                       parentId = act.Project__r.Cust__c;
                    }
where Cust__c is a lookup field
 
SUCHARITA MONDALSUCHARITA MONDAL

Hey Phuc,

Yes, you can use another Map for Project object and Syntax is fine.
Be mindful about variable "ParentId", since it's getting used in different block/scope that may overwrites the values.

 

Thanks,
Sucharita