2

Does a SOQL query have to access the database, or can it be used to search through a list (or map)?

I think lists are easier to visualize, so I would have made a list in a FOR loop for each object to work with. But if it has to hit the database that is a terrible idea. (I figured out a way around it with nested FOR loops)

I think the answer is database only, but I figured I would ask for anyone in the future who has the same question.

List<ID> List1 = new List<ID>();
for (CustomObject__c CO: trigger.new){
    List1.add(CO.CustomField__c);
}

List<CustomObject__c> List2 = new List<CustomObject__c>([
    SELECT CustomField__c
    FROM List1                                  
    ORDER BY CreatedDate                        
    DESC LIMIT 1
]);

2 Answers 2

3

No, you can only search the database, not an object in memory. Usually this means that you'll want to create structures that facilitate locating the data you're looking for ahead of time. For example, if you wanted to find all leads by their lead source in a trigger, you might do this:

Map<String, Lead[]> leadsBySource = new Map<String, Lead[]>();
for(Lead record: Trigger.new) {
    leadsBySource.put(record.LeadSource, new Lead[0]);
}
for(Lead record: Trigger.new) {
    leadsBySource.get(record.LeadSource).add(record);
}

At this point, you can find all the leads that are from a particular lead source. The specifics will depend on what you're searching for. You should always avoid a loop-inside-loop construct when addressing lists, although it's usually acceptable (or even required) to do so for nested collections.

// Bad Idea
for(Lead first: Trigger.new) {
    for(Lead second: Trigger.new) {
        if(first.LeadSource == second.LeadSource) ...

// Good Idea
Map<String, Map<String, Map<String, Lead[]>>> leadData ...
for(String firstKey: leadData.keySet()) {
    for(String secondKey: leadData.get(firstKey)) {
        for(String thirdKey: leadData.get(firstKey).get(secondKey)) {
            for(Lead record: leadData.get(firstKey).get(secondKey).get(thirdKey)) {
                ........
1

To add to @SFDCfox's answer, if the data is in the trigger.new or trigger.newmap or trigger.oldmap, there's no need to query for it. Obviously, it counts against the number of SOQL queries allocated to your org over a 24 hr period. It also slows down your trigger and makes it less efficient.

As you mention lists, maps and sets are generally more efficient than lists. They remove duplicate information and prevent the dreaded "list exception" than can occur when a list contains more than one instance of the same object ID. To be safe, that's when you'll want to test to make certain the list you're adding to doesn't already contain the same object ID. If you put a second instance of the key with an associated value to a Map that contains the same ID, the previous value for that key is overwritten, so no problem and no exception occurs (hopefully you have the desired value, with an ID as the key, that's highly likely; but much less so with a string).

@sfdcfox has clearly explained an excellent method for obtaining nested information from a map.

If you do find yourself searching a database, a map construction is also a valid one to use when constructing your search query, especially if multiple related objects are being queried. There's a simple method for retrieving the data as well using nested for loops that are to me, always seem simpler than above. As that doesn't apply to your particular situation, I won't explain it here since it doesn't apply to your particular use case. It does however result in retrieving all your data in lists.

You'll find an example of a method to use as described in my answer to Salesforce: Apex Update Object And All Child Object Records Associated to Parent Object.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .