Skip to content

Count only the operators that change a query - #32

Merged
SimonCropp merged 1 commit into
mainfrom
operators-that-change-a-query
Oct 9, 2026
Merged

SimonCropp merged 1 commit into
mainfrom
operators-that-change-a-query

Conversation

@SimonCropp

Copy link
Copy Markdown
Owner

MaxOperators counted every call on Queryable, Enumerable and the two Entity Framework extension classes. That included calls that add nothing to the query:

  • ToList and the like, which only say what to hold the results in.
  • Options such as AsNoTracking and AsSplitQuery, which only say how to run it.

A projection ends each collection it returns with a ToList, so every projected collection was counted twice. The query that prompted this is an export selecting eight collections. It measured 35 against the default of 30, and 9 of those were ToList, AsSplitQuery and AsNoTracking. It now measures 26.

No longer counted

  • ToList, ToArray, ToHashSet, AsEnumerable, AsQueryable
  • AsNoTracking, AsNoTrackingWithIdentityResolution, AsTracking, AsSplitQuery, AsSingleQuery, IgnoreAutoIncludes, IgnoreQueryFilters, TagWith, TagWithCallSite

Include and ThenInclude still count, since each adds to what is loaded.

Impact

A count can only go down, so no query starts to log or throw. A throw level chosen against the old counts now allows more.

Changes

  • ShapeAnalyzer.IsOperator decides what counts.
  • Four tests in ShapeTests: subqueries count, what holds the results does not, options do not, includes do.
  • An "Operators" section in the readme, and the XML docs for MaxOperators.
  • Version 0.6.0.

MaxOperators counted every call on Queryable, Enumerable and the two
Entity Framework extension classes. That included calls that add
nothing to the query: ToList and the like, which only say what to hold
the results in, and options such as AsNoTracking and AsSplitQuery,
which only say how to run it.

A projection ends each collection it returns with a ToList, so every
projected collection was counted twice. An export selecting eight
collections measured 35 against the default of 30, with 9 of those
being ToList, AsSplitQuery and AsNoTracking.

Not counted now:

 * ToList, ToArray, ToHashSet, AsEnumerable, AsQueryable
 * AsNoTracking, AsNoTrackingWithIdentityResolution, AsTracking,
   AsSplitQuery, AsSingleQuery, IgnoreAutoIncludes, IgnoreQueryFilters,
   TagWith, TagWithCallSite

Include and ThenInclude still count, since each adds to what is loaded.

A count can only go down, so no query starts to log or throw. A throw
level chosen against the old counts now allows more.

Version 0.6.0.
@SimonCropp SimonCropp added this to the 0.6.0 milestone Oct 9, 2026
@SimonCropp
SimonCropp merged commit 38f76c8 into main Oct 9, 2026
4 checks passed
@SimonCropp
SimonCropp deleted the operators-that-change-a-query branch October 9, 2026 06:16
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.

1 participant