Optimize Group Scheduler query by matching in memory #6663
+41
−14
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.

Refactored attendance occurrence retrieval logic to improve performance by fetching attendance occurrences separately and matching them in memory.
Proposed Changes
The
GetLocationsAndSchedulesmethod in the Group Scheduler block was using a correlated subquery pattern to fetchAttendanceOccurrenceswithin the main LINQ projection. This caused Entity Framework 6 to execute a separate database query for each group/location/schedule combination (N+1 query problem), resulting in poor performance when viewing schedules for multiple groups across several weeks.This PR refactors the data retrieval to use a "fetch then stitch" pattern:
First query: Fetch all
GroupLocationScheduledata, projecting to an anonymous type first to avoid EF6 materialization issues with class constructors, then converting toGroupLocationScheduleobjects in memory with emptyAttendanceOccurrenceslists.Second query: Fetch all relevant
AttendanceOccurrencerecords in a single query usingINclauses based on the distinct group, location, and schedule IDs from the first query.In-memory matching: Iterate through the
GroupLocationScheduleobjects and assign the appropriateAttendanceOccurrencesfrom the second query result.This reduces database round-trips from N+1 (potentially hundreds) down to just 2, significantly improving page load times for the Group Scheduler block.
Fixes: #6662
Types of changes
What types of changes does your code introduce to Rock?
Put an
xin the boxes that applyChecklist
Put an
xin the boxes that apply. You can also fill these out after creating the PR. If you're unsure about any of them, don't hesitate to ask. We're here to help! This is simply a reminder of what we are going to look for before merging your code.Further comments
This is a performance optimization with no functional changes to the Group Scheduler behavior. The same data is retrieved and processed; only the retrieval pattern has changed to reduce database load.
Documentation
No documentation changes required. This is an internal performance optimization with no UI or behavioral changes.
Migrations
If your pull request requires a migration, please exclude the migration from the Rock.Migration project, but submit it with your pull request. Please add a note to your pull request that provides a heads up that a migration file is present.
No migrations required.