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
Priti ShelkePriti Shelke 

How to write below code without hitting apex governor limit

Hi All,
I have written the Apex class for coping all feeditem of lead to converted account and Contact.
The code is working fine but it will not work for above 200 records because I have queried feeditem inside the loop.
for(Lead l:ledlst)
    {
        for(List<feeditem> flst:[Select ParentId,Id, Body,IsRichText From FeedItem Where ParentId =: l.id])
        {
          feedMap.put(l.Id, flst); 
        }
    }
As am new to salesforce I not getting how to optimize this code.
Please help me to write code with best practice.
Entire Class Code:
public class Lead_Convert_Handler 
{
 public void addLeadfeedToAccCont(list<Lead> ledlst)
  {
    list<feedItem> conFeeditm = new list<feedItem>();
    list<feedItem> accFeeditm = new list<feedItem>();    
    Map<Id,list<FeedItem>> feedMap = new Map<Id,list<FeedItem>>();    
    Map<Id,Id> acctIdMap = new Map<Id,Id>();
    Map<Id,Id> contIdMap = new Map<Id,Id>();  
    // add feeditem related to lead to FeedMap  
    for(Lead l:ledlst)
    {
        for(List<feeditem> flst:[Select ParentId,Id, Body,IsRichText From FeedItem Where ParentId =: l.id])
        {
          feedMap.put(l.Id, flst); 
        }
    }
   // loop to add converted acc and cont id to map.   
    for(lead l:ledlst)
    {
      acctIdMap.put(l.id, l.ConvertedAccountId);
      contIdMap.put(l.id, l.ConvertedContactId);  
    }
    system.debug(feedMap);  
    // Copy feeditem from lead to converted contact and account.  
    for(lead l1:ledlst)
    {
        if(!feedMap.isEmpty())
        {
            //for(Id pid:feedMap.keySet())
            //{
            for(feedItem lf:feedMap.get(l1.id))
             {
              if(feedMap.containsKey(l1.Id)&&acctIdMap.containsKey(l1.Id)&&contIdMap.containsKey(l1.Id)&&lf.ParentId == l1.Id) 
                {
                  // create feed for Account  
                  FeedItem accfeed = new FeedItem();
                  accfeed.Body = lf.Body;
                  accfeed.ParentId = acctIdMap.get(l1.Id);
                  accFeeditm.add(accfeed);
                // create feed for Contact
                 FeedItem confeed = new FeedItem();
                 confeed.Body = lf.Body;
                 confeed.ParentId =contIdMap.get(l1.Id);
                 conFeeditm.add(confeed);          
                }
              }
          //  }
        } 
    }
    IF(!accFeeditm.isEmpty())
    insert accFeeditm;
    IF(!conFeeditm.isEmpty())
    insert conFeeditm;   
  }
}

Thanks In advance
Best Answer chosen by Priti Shelke
Priti ShelkePriti Shelke
with small changes, in your code, I find a solution.
set<Id> leadIdSet = new set<Id>();
 for(Lead leadRecord : leadList){
leadIdSet.add(leadRecord.Id);
}
List<feeditem> feedItemList = [Select ParentId, Id, Body, IsRichText From FeedItem Where ParentId IN leadIdSet ];
map<Id, list<feeditem>> leadToFeedItemMap = new map<Id,<feeditem>>();
for(feeditem feedItemRecord : feedItemList ){
if(leadToFeedItemMap.containsKey(feedItemRecord.ParentId)) {
leadToFeedItemMap.get(feedItemRecord.ParentId).add(feedItemRecord);
} else { l
feadToFeedItemMap.put(feedItemRecord.ParentId, new List<feeditem> {feedItemRecord});
 }
}

Thanks for Solution.  

All Answers

Pankaj PPankaj P
Hi Priti,

You can utilize maps here no need to write query inside a for loop. 
set<Id> leadIdSet = new set<Id>();
for(Lead leadRecord : leadList) {
    leadIdSet.add(leadRecord.Id);
}

List<feeditem> feedItemList = [Select ParentId, Id, Body, IsRichText From FeedItem Where ParentId IN leadIdSet ];

map<Id, feeditem > leadToFeedItemMap = new map<Id,feeditem>();
for(feeditem feedItemRecord : feedItemList ){
    leadToFeedItemMap.put(feedItemRecord.ParentId, feedItemRecord);
}
Note : above given code is not tested and can have syntactical errors.

Hope this helps you.
Thanks,
Pankaj.

 
Priti ShelkePriti Shelke
Thanks Pankaj
Appreciate ur time
but the code u have written will work for single feeditem, if I have more feeditem related to lead it only copy 1st feeditem.
Pankaj PPankaj P
Ohh okay, sorry for that, didn't think over that part, so map formation will have lead id to list of feed item list, i.e. a small change in last loop. See the code below : 
 
set<Id> leadIdSet = new set<Id>();
for(Lead leadRecord : leadList) {
    leadIdSet.add(leadRecord.Id);
}

List<feeditem> feedItemList = [Select ParentId, Id, Body, IsRichText From FeedItem Where ParentId IN leadIdSet ];

map<Id, list<feeditem>> leadToFeedItemMap = new map<Id,<feeditem>>();
for(feeditem feedItemRecord : feedItemList ){
    if(leadToFeedItemMap.containsKey(feedItemRecord.ParentId)) {
        leadToFeedItemMap.get(feedItemRecord.ParentId).add(feedItemRecord);
    } else {
         leadToFeedItemMap.put(feedItemRecord.ParentId, feedItemRecord);
    }
}

Note : above given code is not tested and can have syntactical errors.

Hope this helps you.
Thanks,
Pankaj.
Priti ShelkePriti Shelke
with small changes, in your code, I find a solution.
set<Id> leadIdSet = new set<Id>();
 for(Lead leadRecord : leadList){
leadIdSet.add(leadRecord.Id);
}
List<feeditem> feedItemList = [Select ParentId, Id, Body, IsRichText From FeedItem Where ParentId IN leadIdSet ];
map<Id, list<feeditem>> leadToFeedItemMap = new map<Id,<feeditem>>();
for(feeditem feedItemRecord : feedItemList ){
if(leadToFeedItemMap.containsKey(feedItemRecord.ParentId)) {
leadToFeedItemMap.get(feedItemRecord.ParentId).add(feedItemRecord);
} else { l
feadToFeedItemMap.put(feedItemRecord.ParentId, new List<feeditem> {feedItemRecord});
 }
}

Thanks for Solution.  
This was selected as the best answer