Skip to content

Add ChangeTracker.GetEntriesForState()#37847

Merged
AndriySvyryd merged 6 commits intomainfrom
copilot/add-changetracker-getentriesforstate
Mar 4, 2026
Merged

Add ChangeTracker.GetEntriesForState()#37847
AndriySvyryd merged 6 commits intomainfrom
copilot/add-changetracker-getentriesforstate

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 4, 2026

Exposes the internal IStateManager.GetEntriesForState() as a public API on ChangeTracker, enabling efficient querying of tracked entities by state without triggering DetectChanges(). This is critical for long-lived contexts tracking many entities where DetectChanges() is prohibitively expensive.

  • Two new methods on ChangeTracker: non-generic GetEntriesForState() and generic GetEntriesForState<TEntity>(), both accepting boolean flags for added, modified, deleted, unchanged (all default false)
  • No DetectChanges call — unlike Entries(), these bypass change detection entirely, returning current tracker state as-is
  • Tests covering: no-DetectChanges behavior, per-state filtering, combined state queries, type filtering on generic overload
// Get only modified and added entries without triggering DetectChanges
var pending = context.ChangeTracker.GetEntriesForState(added: true, modified: true);

// Same, but scoped to a specific entity type
var pendingProducts = context.ChangeTracker.GetEntriesForState<Product>(added: true, modified: true);
Original prompt

This section details on the original issue you should resolve

<issue_title>Add ChangeTracker.GetEntriesForState()</issue_title>
<issue_description>
In long term contexts the DetectChanges-Method is slow when a lot of objects are tracked. It's a linear or polynomial complexity problem.
See: https://github.com/dotnet/efcore/blob/release/8.0/src/EFCore/ChangeTracking/Internal/ChangeDetector.cs#L129
foreach (var entry in stateManager.ToList()) // Might be too big, but usually _all_ entities are using Snapshot tracking

This could be avoided by a redesign of the change tracker. My suggestions would be, that during the reflection phase where the entity classes are analyzed also some known interfaces should be recognized. In this context it would be the INotifyPropertyChanged-Interface. If a entity class implements this interface and the change tracker is configured as let's call it "Just-In-Time-Tracking-Mode", then changed entites has to be registered in different fast collections according it's EntityState. And a further method should be provided similiar to the historic System.Data.Objects.ObjectStateManager.GetObjectStateEntries() where the searched EntityStates can be passed.

I'm aware that's a critical and central core feature. Especially because of the risk of memory leaks if the garbage collector cannot free objects if events have not been properly unsubscribed. But I would be very happy if such important core-features from previous EF-Versions would be prioritized highly.
</issue_description>

<agent_instructions>See the implementation in https://github.com/iplus-framework/efCoreForPull/blob/9ea960954b7e7a141ab88817d3de619100a45429/src/EFCore/ChangeTracking/ChangeTracker.cs for reference, but generate XML comments from scratch</agent_instructions>

Comments on the Issue (you are @copilot in this section)

@roji @AndriySvyryd this is more up your alley.

🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

…>() methods

Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Copilot AI changed the title [WIP] Add ChangeTracker.GetEntriesForState() to improve performance Add ChangeTracker.GetEntriesForState() Mar 4, 2026
@AndriySvyryd AndriySvyryd marked this pull request as ready for review March 4, 2026 19:11
@AndriySvyryd AndriySvyryd requested a review from a team as a code owner March 4, 2026 19:11
Copilot AI review requested due to automatic review settings March 4, 2026 19:11
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a new public ChangeTracker.GetEntriesForState() API (plus a generic overload) to efficiently enumerate tracked entries by EntityState without triggering DetectChanges(), targeting scenarios with large, long-lived contexts where change detection is too expensive.

Changes:

  • Added ChangeTracker.GetEntriesForState(...) and ChangeTracker.GetEntriesForState<TEntity>(...) APIs which delegate to IStateManager.GetEntriesForState(...) without calling DetectChanges().
  • Added unit tests validating no-DetectChanges behavior, per-state filtering, combined state queries, and generic type filtering.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/EFCore/ChangeTracking/ChangeTracker.cs Introduces the two new public GetEntriesForState* APIs and XML documentation.
test/EFCore.Tests/ChangeTracking/ChangeTrackerTest.cs Adds coverage for filtering and the “does not call DetectChanges” guarantee.

You can also share your feedback on Copilot code review. Take the survey.

Comment thread src/EFCore/ChangeTracking/ChangeTracker.cs Outdated
Comment thread test/EFCore.Tests/ChangeTracking/ChangeTrackerTest.cs Outdated
AndriySvyryd and others added 2 commits March 4, 2026 12:08
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Comment thread src/EFCore/ChangeTracking/ChangeTracker.cs Outdated
@AndriySvyryd
Copy link
Copy Markdown
Member

Thanks to @DamirLisak for inspiration

@AndriySvyryd AndriySvyryd enabled auto-merge (squash) March 4, 2026 21:31
@AndriySvyryd AndriySvyryd merged commit 251f5d3 into main Mar 4, 2026
10 checks passed
@AndriySvyryd AndriySvyryd deleted the copilot/add-changetracker-getentriesforstate branch March 4, 2026 22:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add ChangeTracker.GetEntriesForState()

4 participants