Agent Skills: LINQ Optimization Patterns

LINQ and EF Core query optimization for ABP Framework. N+1 prevention, eager loading, projections, pagination.

UncategorizedID: thapaliyabikendra/ai-artifacts/linq-optimization-patterns

Install this agent skill to your local

pnpm dlx add-skill https://github.com/thapaliyabikendra/ai-artifacts/tree/HEAD/.claude/skills/linq-optimization-patterns

Skill Files

Browse the full folder contents for linq-optimization-patterns.

Download Skill

Loading file tree…

.claude/skills/linq-optimization-patterns/SKILL.md

Skill Metadata

Name
linq-optimization-patterns
Description
"LINQ and EF Core query optimization for ABP Framework. N+1 prevention, eager loading, projections, pagination."

LINQ Optimization Patterns

Optimize LINQ queries and prevent performance anti-patterns in EF Core/ABP applications.


Summary

This skill covers efficient data access patterns for Entity Framework Core in ABP Framework applications. Focus areas: N+1 prevention, pagination, projections, and batch loading.

When to use: Reviewing queries, fixing slow endpoints, implementing list APIs.


Concepts

| Concept | Description | Details | |---------|-------------|---------| | Eager Loading | Load related entities in single query via JOIN | [patterns/eager-loading.md] | | Projection | Transform to DTO at database level | [patterns/projection.md] | | Batch Loading | Load related data for multiple parents in one query | [patterns/batch-loading.md] | | Pagination | Efficient paging with count optimization | [patterns/pagination.md] |


Anti-Patterns

| Anti-Pattern | Severity | Detect | Impact | Details | |--------------|----------|--------|--------|---------| | N+1 Query | πŸ”΄ HIGH | foreach.*await.*Repo | N+1 DB calls | [anti-patterns/n-plus-one.md] | | Count After Pagination | πŸ”΄ HIGH | Count.*after.*ToList | Double query | [anti-patterns/count-after-pagination.md] | | Full Table Load | πŸ”΄ HIGH | GetListAsync() then filter | Memory explosion | [anti-patterns/full-table-load.md] | | In-Memory Join | πŸ”΄ HIGH | Multiple ToListAsync | Cartesian in memory | [anti-patterns/in-memory-join.md] |


Decision Tree

Need related data for display?
β”œβ”€ Single entity ──────────► Include()        β†’ [patterns/eager-loading.md]
β”œβ”€ List of entities ───────► Batch load       β†’ [patterns/batch-loading.md]
└─ Only specific fields ───► Projection       β†’ [patterns/projection.md]

Need paginated list with count?
└─ Always count FIRST ─────► CountAsync()     β†’ [patterns/pagination.md]

Loading data then filtering?
β”œβ”€ Filter in query ────────► WhereIf()        β†’ βœ… Correct
└─ Filter after ToList ────► ❌ Anti-pattern  β†’ [anti-patterns/full-table-load.md]

Quick Detection

Run these to find issues in your codebase:

# N+1: Query inside loop
grep -rn "foreach.*await.*Repository\|for.*await.*GetAsync" src/

# Count after pagination
grep -rn "\.Count().*ToList\|ToList.*\.Count()" src/

# Full table load
grep -rn "GetListAsync()" src/ | grep -v "Where\|Any\|First"

# In-memory filtering
grep -rn "ToListAsync().*\.Where\|GetListAsync.*\.Where" src/

Rules

| ID | Rule | Related | |----|------|---------| | R001 | Execute CountAsync() before Skip/Take | [anti-patterns/count-after-pagination.md] | | R002 | Apply Where clauses before ToListAsync() | [anti-patterns/full-table-load.md] | | R003 | Load related entities via Include or batch, not in loops | [anti-patterns/n-plus-one.md] | | R004 | Use Select() projection for DTO returns | [patterns/projection.md] | | R005 | Use AsNoTracking() for read-only queries | [patterns/projection.md] | | R006 | Use AsSplitQuery() for multiple collection includes | [patterns/eager-loading.md] |


Checklist

Review checklist for LINQ queries:

  • [ ] No foreach/for with await repository calls inside
  • [ ] CountAsync() executed before Skip/Take
  • [ ] No GetListAsync() followed by .Where() in memory
  • [ ] No FirstOrDefault inside Select projections
  • [ ] Related data loaded via Include or batch query
  • [ ] Select() projection used for DTO returns
  • [ ] AsNoTracking() used for read-only queries
  • [ ] Multiple collection includes use AsSplitQuery()

Integration Points

This skill is used by:

  • abp-code-reviewer: Query performance validation
  • abp-developer: Efficient data access implementation
  • debugger: Performance issue diagnosis

Related Skills