Skip to content

MA0029: Suppress all Where().X() diagnostics on IQueryable - #1017

Merged
meziantou merged 4 commits into
mainfrom
copilot/improve-ma0029-analyzer
Feb 20, 2026
Merged

MA0029: Suppress all Where().X() diagnostics on IQueryable#1017
meziantou merged 4 commits into
mainfrom
copilot/improve-ma0029-analyzer

Conversation

Copilot AI commented Feb 19, 2026

Copy link
Copy Markdown
Contributor

MA0029 was flagging Where().X() calls on IQueryable<T> as combinable, but for database-backed queryables the generated SQL is identical regardless — combining them only hurts readability.

Changes

  • Analyzer (OptimizeLinqUsageAnalyzer.cs): In CombineWhereWithNextMethod, skip all CombineLinqMethodsRule diagnostics when both methods originate from System.Linq.Queryable (i.e., the chain is on IQueryable<T>).
  • Tests (OptimizeLinqUsageAnalyzerCombineLinqMethodsTests.cs): Updated CombineWhereWithTheFollowingWhereMethod_IQueryable to expect no diagnostic, and added CombineWhereWithTheFollowingMethod_IQueryable covering Any, First, Count, etc.

Behavior

// IQueryable — no longer reported (readability > no-op optimization)
dbContext.Items
    .Where(x => x.CompanyId == a && x.DepartmentId == b)
    .Where(x => ids.Contains(x.Id));

dbContext.Items
    .Where(x => x.IsActive)
    .Any();

// IEnumerable — still reported as before
enumerable.Where(x => x == 0).Where(y => true); // MA0029
enumerable.Where(x => x == 0).Any();            // MA0029
Original prompt

This section details on the original issue you should resolve

<issue_title>Improve MA0029 to be less aggressive (or absent) on IQueryable</issue_title>
<issue_description>Kudos on this fantastic set of analyzers. My colleagues and I are very happy with it.

Here is an improvement request for MA0029:

await dbContext.SomeDbSet
  .Where(item => item.CompanyId == a && item.DepartmentId == b)
  .Where(item => itemIds.Contains(item.Id))

MA0029 wants me to combine the Where calls, but that would reduce readability.

I would like the analyzer to be more aware of IQueryable<T>. In the simplest case, it could be ignore for that type altogether. Ideally, it would be less aggressive for that type. Readability is important for queries. Doing two calls to Where no meaningful performance impact, since the resulting query tends to be identical.

I'm on the fence about optimizations such as combining .Where() with .AnyAsync(). On the one hand, a developer might not be aware of the possibility. On the other, they might find the result clearer when a Where() is explicit. (Suppressing looks rather ugly, and I absolutely loathe and despise leaving suggestions unhandled. The boy who cried wolf...)

In general, I conclude that the analyzer should be rather permissive on IQueryable<T>, but there may still exist cases that are worth reporting even there.</issue_description>

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


🔒 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.

Co-authored-by: meziantou <509220+meziantou@users.noreply.github.com>
Copilot AI changed the title [WIP] Improve MA0029 to reduce aggressiveness on IQueryable MA0029: Suppress Where().Where() diagnostic on IQueryable Feb 19, 2026
Copilot AI requested a review from meziantou February 19, 2026 16:08
@meziantou

Copy link
Copy Markdown
Owner

@copilot Apply similar change for CombineLinqMethodsRule

Co-authored-by: meziantou <509220+meziantou@users.noreply.github.com>

Copilot AI commented Feb 20, 2026

Copy link
Copy Markdown
Contributor Author

@copilot Apply similar change for CombineLinqMethodsRule

Done in 9b9a68d. Removed the Where().Where() restriction — now all Where().X() combinations (Any, First, Count, etc.) are suppressed on IQueryable<T>.

Copilot AI changed the title MA0029: Suppress Where().Where() diagnostic on IQueryable MA0029: Suppress all Where().X() diagnostics on IQueryable Feb 20, 2026
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.

Improve MA0029 to be less aggressive (or absent) on IQueryable

2 participants