+ Start a Discussion
Michael MMichael M 

Remove Query from For Loop

Can someone help- i need to rewrite the below trigger, with the same effects, but with remove all SOQL queries from inside the for loop:

trigger CdlUpdateDischarge on ContentDocumentLink (after insert) {
    Set <string> setlinkedid = new set<string>();
    for (ContentDocumentLink cd : trigger.new){
            setlinkedid.add(cd.linkedentityid);
        List<Discharge__c> disList = [select id from discharge__c where id=:setlinkedid];
        List<contentdocumentlink> cdl = [SELECT ContentDocumentId
                                     FROM ContentDocumentLink 
                                     WHERE LinkedEntityId in (select id from discharge__c where id=:setlinkedid)];
        try{
        if (cdl.size() > 0 && cdl.size() < 2){
            for (Discharge__c dis : disList){
            dis.Referrals_Status__c = 'Documents Uploaded';
            }
            update disList;
        }    
        }catch(exception e){
            system.debug(e);
        }
        
    }
    
}
Best Answer chosen by Michael M
ayu sharma devayu sharma dev
Hello Michael

Please try the following code.
 
trigger CdlUpdateDischarge on ContentDocumentLink (after insert) {
    Map<Id, List<Discharge__c>> mapLinkedIdToDischarges = new Map<Id, List<Discharge__c>>();
    Map<Id, List<contentdocumentlink>> mapContentDocs = new Map<Id, List<contentdocumentlink>>();
    List<Discharge__c> disToUpdate = new List<Discharge__c>();

    for( ContentDocumentLink cd : trigger.new ){
        mapLinkedIdToDischarges.put( cd.linkedentityid, null );
    }

    for( Discharge__c ds : [select id from discharge__c where id IN: mapLinkedIdToDischarges.keyset() ] ){
        if( mapLinkedIdToDischarges.get( ds.Id ) == null ){
            mapLinkedIdToDischarges.put( ds.Id, new List< Discharge__c >{ ds } );
        }
        else{
            mapLinkedIdToDischarges.get( ds.Id ).add( ds );
        }
    }

    for( contentdocumentlink cdLink : [SELECT ContentDocumentId, LinkedEntityId
                                        FROM ContentDocumentLink 
                                        WHERE LinkedEntityId in (select id from discharge__c where id IN:mapLinkedIdToDischarges.keyset())] ){
        if( mapContentDocs.get( cdLink.LinkedEntityId ) == null ){
            mapContentDocs.put( cdLink.LinkedEntityId, new List<contentdocumentlink>{ cdLink } );
        }
        else{
            mapContentDocs.get( cdLink.LinkedEntityId ).add( cdLink );
        }
    }

    for (ContentDocumentLink cd : trigger.new){
        List<Discharge__c> disList;
        List<contentdocumentlink> cdl;
        if( mapLinkedIdToDischarges.containsKey( cd.linkedentityid ) ){
            disList = mapLinkedIdToDischarges.get( cd.linkedentityid );
            cdl = mapContentDocs.get( cd.linkedentityid );
        }
        disList = disList != null ? disList : new List<Discharge__c>();
        try{
        if (cdl != null && cdl.size() > 0 && cdl.size() < 2){
            for (Discharge__c dis : disList){
                dis.Referrals_Status__c = 'Documents Uploaded';
            }
        }    
        }catch(exception e){
            system.debug(e);
        }
        disToUpdate.addAll( disList );
        
    }
    if( disToUpdate.size() > 0 ){
        update disToUpdate;
    }
}

I hope it helps. Let me know if any problem arises. 

Thanks and Regards 
Ayush Sharma

All Answers

MagulanDuraipandianMagulanDuraipandian
trigger CdlUpdateDischarge on ContentDocumentLink ( after insert ) {

    Set < String > setlinkedid = new set< String >();
    Map < Id, Discharge__c > mapDisch = new Map <Id, Discharge__c >();
    
    for ( ContentDocumentLink cd : trigger.new ){

        if ( cd.LinkedEntityId.getSObjectType().getDescribe().getName() == 'Discharge__c' ) {
            
            if ( !mapDisch.containsKey( cd.LinkedEntityId ) ) {
            
                Discharge__c objDisch = new Discharge__c();
                objDisch.Id = cd.LinkedEntityId;
                objDisch.Referrals_Status__c = 'Documents Uploaded';
                mapDisch.put( cd.LinkedEntityId, objDisch );
            
            }
        
        }
                
    }
    
    if ( mapDisch.size() > 0 ) {
    
        try { 
            update mapDisch.values();
        } catch(exception e){
            system.debug(e);
        }
    
    }
    
}

--
Magulan Duraipandian
www.infallibletechie.com
ayu sharma devayu sharma dev
Hello Michael

Please try the following code.
 
trigger CdlUpdateDischarge on ContentDocumentLink (after insert) {
    Map<Id, List<Discharge__c>> mapLinkedIdToDischarges = new Map<Id, List<Discharge__c>>();
    Map<Id, List<contentdocumentlink>> mapContentDocs = new Map<Id, List<contentdocumentlink>>();
    List<Discharge__c> disToUpdate = new List<Discharge__c>();

    for( ContentDocumentLink cd : trigger.new ){
        mapLinkedIdToDischarges.put( cd.linkedentityid, null );
    }

    for( Discharge__c ds : [select id from discharge__c where id IN: mapLinkedIdToDischarges.keyset() ] ){
        if( mapLinkedIdToDischarges.get( ds.Id ) == null ){
            mapLinkedIdToDischarges.put( ds.Id, new List< Discharge__c >{ ds } );
        }
        else{
            mapLinkedIdToDischarges.get( ds.Id ).add( ds );
        }
    }

    for( contentdocumentlink cdLink : [SELECT ContentDocumentId, LinkedEntityId
                                        FROM ContentDocumentLink 
                                        WHERE LinkedEntityId in (select id from discharge__c where id IN:mapLinkedIdToDischarges.keyset())] ){
        if( mapContentDocs.get( cdLink.LinkedEntityId ) == null ){
            mapContentDocs.put( cdLink.LinkedEntityId, new List<contentdocumentlink>{ cdLink } );
        }
        else{
            mapContentDocs.get( cdLink.LinkedEntityId ).add( cdLink );
        }
    }

    for (ContentDocumentLink cd : trigger.new){
        List<Discharge__c> disList;
        List<contentdocumentlink> cdl;
        if( mapLinkedIdToDischarges.containsKey( cd.linkedentityid ) ){
            disList = mapLinkedIdToDischarges.get( cd.linkedentityid );
            cdl = mapContentDocs.get( cd.linkedentityid );
        }
        disList = disList != null ? disList : new List<Discharge__c>();
        try{
        if (cdl != null && cdl.size() > 0 && cdl.size() < 2){
            for (Discharge__c dis : disList){
                dis.Referrals_Status__c = 'Documents Uploaded';
            }
        }    
        }catch(exception e){
            system.debug(e);
        }
        disToUpdate.addAll( disList );
        
    }
    if( disToUpdate.size() > 0 ){
        update disToUpdate;
    }
}

I hope it helps. Let me know if any problem arises. 

Thanks and Regards 
Ayush Sharma
This was selected as the best answer
Michael MMichael M
Thank you both very much. I used Magulan's and it worked. But Ayush-- I will reference yours and learn from it. 
Michael MMichael M
Ayush- your code fits better as it accounts for only the first document being uploaded. 
Michael MMichael M
@Magulan

If this line:  
if ( mapDisch.size() > 0 ) 
was changed to if ( mapDisch.size() > 0 && mapDisch.size() < 2)
Would that only change the discharge status to 'Documents Uploaded' if this is the very first file being uploaded? 
Ashish Chaudhari 56Ashish Chaudhari 56
I have written a batch that an email will be sent to the user to whom a lead is assigned.. In the finish method, how can I remove a query from for loop?


global class BatchOnLead implements Database.Batchable<sObject>, Database.Stateful{
    public List<Id> userId = new List<Id>();
    global Database.QueryLocator start(Database.BatchableContext bc) {
        return Database.getQueryLocator(
            'SELECT Id, OwnerID FROM Lead'
        );
    }
    global void execute(Database.BatchableContext bc, List<Lead> scope){
        system.debug('Called......');
        List<Lead> lstAccount = new List<Lead>();
        for (Lead leads : scope) {
            system.debug('leads.OwnerID : '+leads.OwnerID);
            userId.add(leads.OwnerID);
        }
        system.debug('userId : '+userId);
    }
    
    global void finish(Database.BatchableContext bc){
        
        for(Integer i=0; i<userId.size(); i++) {
            List<User> email = [SELECT Email FROM User WHERE Id =: userId[i]];
            
            Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
            String[] toAddresses = new String[] {email[0].Email};
            mail.setToAddresses(toAddresses);
            mail.setSubject('Lead Assigned ');
            mail.setPlainTextBody('You Have been Assigned a Lead.. Please Check.');
            Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
        }
    }
}