From kagents
EF Core query performance — N+1 detection, compiled queries, split queries, query tags, AsNoTracking, index strategy (composite, filtered, covering), read/write DbContext separation. USE FOR: diagnosing slow queries, optimizing EF Core performance, designing database indexes. DO NOT USE FOR: DbContext setup or migrations (use efcore-patterns) or general database schema design (use database-engineer agent).
npx claudepluginhub grexyloco/k.agentsThis skill uses the workspace's default tool permissions.
Adaptiert von: [Aaronontheweb/dotnet-skills](https://github.com/Aaronontheweb/dotnet-skills) (MIT)
Guides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Guides building MCP servers enabling LLMs to interact with external services via tools. Covers best practices, TypeScript/Node (MCP SDK), Python (FastMCP).
Share bugs, ideas, or general feedback.
Adaptiert von: Aaronontheweb/dotnet-skills (MIT)
// ❌ N+1 Problem
var users = await context.Users.ToListAsync();
foreach (var user in users)
{
var orders = user.Orders; // Lazy Load = 1 Query pro User!
}
// ✅ Eager Loading
var users = await context.Users
.Include(u => u.Orders)
.AsNoTracking()
.ToListAsync();
// ✅ Projection (noch besser)
var dtos = await context.Users
.Select(u => new UserWithOrderCountDto(u.Id, u.Email, u.Orders.Count))
.ToListAsync();
// Bei Include-Chains > 2 Ebenen: AsSplitQuery()
var orders = await context.Orders
.Include(o => o.Items)
.ThenInclude(i => i.Product)
.ThenInclude(p => p.Category)
.AsSplitQuery() // Verhindert Cartesian Explosion
.ToListAsync();
private static readonly Func<AppDbContext, Guid, Task<User?>> GetUserById =
EF.CompileAsyncQuery((AppDbContext ctx, Guid id) =>
ctx.Users.AsNoTracking().FirstOrDefault(u => u.Id == id));
// Nutzung
var user = await GetUserById(context, userId);
var users = await context.Users
.TagWith("GetActiveUsers - UserService.cs:42")
.Where(u => u.IsActive)
.ToListAsync();
// Tag erscheint im SQL-Log → einfache Zuordnung
// Häufige WHERE-Klausel → Index
builder.HasIndex(u => u.Email).IsUnique();
// Composite Index für Multi-Column-Queries
builder.HasIndex(o => new { o.UserId, o.CreatedAt });
// Filtered Index für Soft-Delete
builder.HasIndex(u => u.Email)
.HasFilter("[IsDeleted] = 0");
// Covering Index (Include)
builder.HasIndex(u => u.LastName)
.IncludeProperties(u => new { u.FirstName, u.Email });
// Separate DbContexte für Read und Write
services.AddDbContext<ReadDbContext>(o => o
.UseSqlServer(config["ReadReplica"])
.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking));
services.AddDbContext<WriteDbContext>(o => o
.UseSqlServer(config["Primary"]));
AsNoTracking() bei allen Read-Only QueriesAsSplitQuery() bei tiefen Include-ChainsSelect() Projection statt volle Entities laden