Documentation
EF Core Analyzer Rules
A practical guide to LinqContraband's EF Core analyzer rules for query performance, loading, tracking, async execution, raw SQL safety, and CI policy.
EF Core Analyzer Rules
LinqContraband provides 63 EF Core analyzer rules for teams that want repeatable query review in the IDE and CI. The rules cover LINQ query shape, materialization, loading, async execution, tracking, bulk operations, schema modeling, and raw SQL safety.
Install the official analyzer package:
dotnet add package LinqContraband
Rule Families
Use these groups to decide which EF Core diagnostics are most useful for your project before diving into the full rule catalog.
| Rule family | Use it when you want to catch | Starting rules |
|---|---|---|
| Query shape and translation | Local methods, unstable ordering, non-translatable overloads, sorts that Distinct discards, query shapes that can fall out of SQL translation, and compiled queries that are compiled again on every call. |
EF Core client-side evaluation analyzer, LC001: local method, LC050: OrderBy before Distinct, LC061: compiled query not cached, EF Core pagination OrderBy analyzer |
| Materialization and projection | Early ToList, whole-entity fetches, unbounded result sets, nested collection materializers, scalar reads that should project in SQL, and Min/Max/Average calls that throw when no row matches. |
EF Core projection analyzer, LC017: whole entity projection, LC057: Min, Max or Average on an empty query, EF Core premature materialization analyzer |
| Loading and includes | Missing includes, cartesian explosion, excessive eager loading, deep include chains, includes that a projection ignores, and untagged complex queries. | LC045: missing include, LC049: Include ignored by a projection, LC006: cartesian explosion, EF Core Include analyzer |
| Execution and async | Database work inside loops, synchronous or overlapping same-context EF Core calls, repeated saves, missing cancellation tokens, async-stream buffering, TransactionScopes that do not flow across await, EF Core async operators on in-memory AsQueryable() queries, blocking on EF Core tasks with .Result or .Wait(), and transactions started outside a retrying execution strategy. |
LC046: concurrent DbContext operations, LC058: TransactionScope without async flow, LC060: async operator on an in-memory query, LC062: blocking on an EF Core async call, LC063: transaction under a retrying execution strategy, EF Core async query analyzer, EF Core CancellationToken analyzer |
| Tracking and context lifetime | Missing AsNoTracking, no-tracking writes, mixed tracking modes, repeated SaveChanges, lost updates without a concurrency token, DbContext lifetime mistakes, and disposing the connection the context owns. |
LC030: DbContext lifetime, LC048: lost update risk, LC059: disposed context connection, LC036: context captured across threads, EF Core DbContext lifetime analyzer |
| Bulk operations and modeling | Set-based write opportunities, unbounded bulk updates or deletes, tracked-delete pipeline bypasses, missing keys, missing explicit foreign keys, seed data or column defaults that change on every run, migrations that EF Core 9 rejects inside a transaction, and OnModelCreating overrides that skip the base configuration. |
LC047: ExecuteDelete bypasses tracked delete, LC054: Migrate inside a transaction, LC055: missing base.OnModelCreating, LC032: ExecuteUpdate, LC035: missing Where before bulk execute, EF Core ExecuteUpdate analyzer |
| Raw SQL and security | Interpolated raw SQL, constructed SQL strings, unsafe command SQL, LINQ composed over stored procedure calls, and query-filter bypasses. | LC018: interpolated raw SQL, LC034: interpolated command SQL, LC056: LINQ over a stored procedure, LC021: IgnoreQueryFilters |
Rules To Enable First
For a low-noise rollout, start with the rules that usually represent clear production risk:
[*.cs]
# Repeated database work and missing related data
dotnet_diagnostic.LC007.severity = error
dotnet_diagnostic.LC045.severity = warning
# Raw SQL and query-filter bypasses
dotnet_diagnostic.LC018.severity = error
dotnet_diagnostic.LC034.severity = error
dotnet_diagnostic.LC037.severity = error
dotnet_diagnostic.LC021.severity = warning
# Expensive query shapes
dotnet_diagnostic.LC001.severity = warning
dotnet_diagnostic.LC002.severity = warning
dotnet_diagnostic.LC014.severity = warning
dotnet_diagnostic.LC015.severity = warning
dotnet_diagnostic.LC020.severity = warning
dotnet_diagnostic.LC024.severity = warning
dotnet_diagnostic.LC031.severity = warning
dotnet_diagnostic.LC036.severity = warning
# Async EF Core execution
dotnet_diagnostic.LC008.severity = warning
dotnet_diagnostic.LC026.severity = suggestion
dotnet_diagnostic.LC043.severity = suggestion
dotnet_diagnostic.LC046.severity = warning
# Silent data loss
dotnet_diagnostic.LC044.severity = warning
dotnet_diagnostic.LC047.severity = warning
dotnet_diagnostic.LC048.severity = warning
Keep broader design guidance as warnings until the team has reviewed existing findings. Promote a rule to error only
when it represents project policy and developers have a documented exception path.
Where Each Rule Fits
- Use the EF Core query performance checklist when you need a reviewer-friendly pull-request aid.
- Use the EF Core client-side evaluation analyzer guide
when local methods in
IQueryable, early client boundaries, string comparison overloads, or non-translatableGroupByprojections are the main concern. - Use the EF Core pagination OrderBy analyzer guide when missing
OrderBybeforeSkip,Take,Last,ElementAt, orChunkis the main concern. - Use the EF Core DbContext lifetime analyzer guide when scoped lifetime, singleton services, background workers, disposed queries, or cross-thread capture are the main concern.
- Use the EF Core async query analyzer guide when sync-over-async,
missing cancellation tokens,
ToListAsync, async streams, orSaveChangesAsyncloops are the main concern. - Use the EF Core CancellationToken analyzer guide when
ToListAsync,FirstOrDefaultAsync,SaveChangesAsync, or other async EF Core calls should receive the available operation token. - Use the EF Core premature materialization analyzer guide
when early
ToList,AsEnumerable, unbounded materialization, or projection waste are the main concern. - Use the EF Core projection analyzer guide when whole-entity loads,
scalar projection, nested
ToListinsideSelect, or redundant identitySelectcalls are the main concern. - Use the EF Core Include analyzer guide when missing related data, cartesian explosion, or over-eager loading are the main concern.
- Use the EF Core N+1 query detector guide when repeated database calls or loading strategy are the main concern.
- Use the EF Core raw SQL injection analyzer guide when raw SQL, command SQL, or query-filter bypasses need stronger review.
- Use the EF Core AsNoTracking analyzer guide when read-only query tracking, mixed tracking modes, or no-tracking write paths are the main concern.
- Use the EF Core ExecuteUpdate analyzer guide when tracked bulk
loops,
RemoveRangedeletes, or unfiltered set-based writes are the main concern. - Use the EF Core SaveChanges in loop analyzer guide when repeated saves, N+1 writes, or batched write policy are the main concern.
- Use the EF Core query analyzer CI guide when selected rules should warn or fail pull requests.
- Use the full rule catalog for every rule’s severity, category, sample folder, and code-fix status.
Official Links
- Canonical repository: github.com/georgepwall1991/LinqContraband
- Official NuGet package: nuget.org/packages/LinqContraband
- Documentation hub: georgepwall1991.github.io/LinqContraband
- Safe install guidance: Official LinqContraband downloads and authenticity