Refactoring APEX to keep all database calls outside of for loops I have the following APEX code. I have been trying for hours to try and refactor it so that the SOQL query is outside of the for loop without any luck. Any ideas?

public static void ErrorIfWorklogsOverlap(List&lt;Worklog__c&gt; worklogs) {
        for (Worklog__c worklog : worklogs) {
            List&lt;Worklog__c&gt; timesheetWorklogs = [
                    SELECT
                            Id
                    FROM Worklog__c
                    WHERE Timesheet__c IN (
                            SELECT
                                    Id
                            FROM Timesheet__c
                    )
            ];
            DateTime worklogStartTime = worklog.Start_Time__c;
            DateTime worklogEndTime = worklog.End_Time__c;
            for (Worklog__c checkLog : timesheetWorklogs) {
                DateTime checkLogStart = checkLog.Start_Time__c;
                DateTime checkLogEnd = checkLog.End_Time__c;
                if (worklogStartTime &gt; checkLogStart &amp;&amp; worklogStartTime &lt; checkLogEnd) {
                    worklog.Start_Time__c.addError('Worklog\'s start time is within the bounds of another worklog');
                } else if (worklogEndTime &lt; checkLogEnd &amp;&amp; worklogEndTime &gt; checkLogStart) {
                    worklog.End_Time__c.addError('Worklog\'s end time is within the bounds of another worklog');
                } else if (worklogStartTime &lt; checkLogStart &amp;&amp; worklogEndTime &gt; checkLogEnd) {
                    worklog.addError('Worklog overlaps another worklog');
                }
            }
        }
    }


A Worklog belongs to a Timesheet. This code is supposed to be checking if any of the Worklogs in the list worklogs overlaps another Worklog in the same Timesheet.
The first step would be to create a set of Timelogs that you are interested in and then query for the related Worklogs. Querying Timelogs and getting child Worklogs is probably the simplest solution.

Sample code:

Set&lt;Id&gt; timelogIds = new Set&lt;Id&gt;();
for (Worklog__c worklog : worklogs) {
  timelogIds.add(worklog.Timelog__c);
}

// Get timelogs and related child worklogs
Map&lt;Id, Timelog__c&gt; timeLogs = new Map&lt;Id, Timelog__c&gt;(
                             [SELECT Id,
                             (SELECT ... FROM Worklogs__r) //query child relationship
                             FROM Timelog__c 
                             WHERE Id IN :timelogIds]);

for (Worklog__c worklog : worklogs) {
  List&lt;Worklog__c&gt; tempList = timeLogs.get(worklog.Timelog__c).Worklogs__r;
  // iterate through tempList to check for overlapping records
}