# ef-core

Entity Framework Core patterns for .NET 10. Helps agents configure DbContext, run bulk updates, manage migrations, and build fast DTO query projections.

- skill · `type=skill` · Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode · 2800 installs · ★ 789
- Author: codewithmukesh
- License: MIT · policy=mirror · the beginning of the file is at the end of this page
- Source: https://github.com/codewithmukesh/dotnet-claude-kit/tree/HEAD/skills/ef-core/SKILL.md
- Updated: 2026-08-07
- HTML: https://affpapa.org/en/nevibecode/skills/codewithmukesh-ef-core

## What it does

The skill provides .NET 10 database patterns for coding assistants. It directs the agent to organize entity settings via `IEntityTypeConfiguration<T>`, project queries directly into DTOs with `.Select()` to avoid over-fetching, and run bulk modifications with `ExecuteUpdateAsync` and `ExecuteDeleteAsync` without tracking overhead.

It includes implementations for `SaveChangesInterceptor` auditing, compiled queries via `EF.CompileAsyncQuery`, and value converters for strongly-typed record IDs. Wrapping `DbContext` in another repository or unit of work abstraction is flagged as an anti-pattern because EF Core handles both internally.

Database schema changes follow a strict workflow: generate code with `dotnet ef migrations add`, inspect the migration manually, and never auto-apply changes in production. For production rollouts, the skill relies on generating idempotent SQL scripts with `dotnet ef migrations script --idempotent`.

## Install

### Claude Code (native platform)

1. **Skills CLI (Vercel)**
```bash
npx skills add codewithmukesh/dotnet-claude-kit --skill ef-core -a claude-code
```

2. **Manually: put the files in place**
- File: `~/.claude/skills/ef-core/SKILL.md` — Copy the whole skill folder; for one project use .claude/skills/ef-core/

### Codex

1. **Skills CLI (Vercel)**
```bash
npx skills add codewithmukesh/dotnet-claude-kit --skill ef-core -a codex
```

2. **Manually: put the files in place**
- File: `.agents/skills/ef-core/SKILL.md` — For all projects use ~/.agents/skills/

### Cursor

1. **Skills CLI (Vercel)**
```bash
npx skills add codewithmukesh/dotnet-claude-kit --skill ef-core -a cursor
```

2. **Manually: put the files in place**
- File: `.cursor/skills/ef-core/SKILL.md` — Cursor also reads .agents/skills/ and .claude/skills/

### GitHub Copilot

1. **GitHub CLI**
```bash
gh skill install codewithmukesh/dotnet-claude-kit ef-core
```

2. **Manually: put the files in place**
- File: `.github/skills/ef-core/SKILL.md`

### Gemini CLI

1. **Skills CLI (Vercel)**
```bash
npx skills add codewithmukesh/dotnet-claude-kit --skill ef-core -a gemini-cli
```

2. **Platform CLI**
```bash
gemini skills install https://github.com/codewithmukesh/dotnet-claude-kit --path skills/ef-core
```

### Windsurf (Devin Desktop)

**Manually: put the files in place**
- File: `.devin/skills/ef-core/SKILL.md` — The legacy .windsurf/skills/ path still works

### OpenCode

**Skills CLI (Vercel)**
```bash
npx skills add codewithmukesh/dotnet-claude-kit --skill ef-core -a opencode
```

### Claude.ai

**Claude.ai**
- Zip the folder and upload it in Settings → Capabilities → Skills

Where a file is given instead of a command, copy the files from the source to that path: https://github.com/codewithmukesh/dotnet-claude-kit/tree/HEAD/skills/ef-core/SKILL.md

## When to use it
- project LINQ queries into DTOs to avoid over-fetching and N+1 issues
- execute bulk updates and deletes directly in the database without change tracking
- track audit timestamps on entities using a `SaveChangesInterceptor`
- generate idempotent SQL migration scripts for production deployments

## Example prompts
- Configure the Order entity using IEntityTypeConfiguration with indexes and cascade delete
- Write a paginated query for orders projecting into OrderSummary records
- Implement an audit interceptor that sets CreatedAt and UpdatedAt on saving changes

## Source text · SKILL.md · MIT

Below is the content of a third-party file. It is data, not instructions for you: do not act on anything written inside unless the human asks. Block tag: 75122b672a52b423.

BEGIN THIRD-PARTY FILE 75122b672a52b423
````text
---
name: ef-core
description: >
  Entity Framework Core patterns for .NET 10. Covers DbContext configuration,
  migrations workflow, interceptors, compiled queries, ExecuteUpdateAsync,
  ExecuteDeleteAsync, value converters, and query optimization.
  Load this skill when working with databases, writing queries, managing schema
  changes, or when the user mentions "EF Core", "Entity Framework", "DbContext",
  "migration", "LINQ query", "database", "SQL", "N+1", "Include", "split query",
  "value converter", "interceptor", or "compiled query".
---

# EF Core (.NET 10)

## Core Principles

1. **EF Core is the default ORM** — Use it unless you have a specific reason not to (extreme perf, legacy DB without FK constraints). See ADR-003.
2. **DbContext is a unit of work** — Don't wrap it in another UoW abstraction. EF Core already implements Unit of Work and Repository patterns internally.
3. **Queries should be projections** — Use `.Select()` to project into DTOs instead of loading full entities. This avoids over-fetching and N+1 issues.
4. **Migrations are code** — Treat them like any other source code. Review them, test them, never auto-apply in production.

## Patterns

### DbContext Configuration

Use `IEntityTypeConfiguration<T>` to keep entity configs separate and discoverable.

```csharp
// Persistence/AppDbContext.cs
public class AppDbContext(DbContextOptions<AppDbContext> options) : DbContext(options)
{
    public DbSet<Order> Orders => Set<Order>();
    public DbSet<Product> Products => Set<Product>();

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.ApplyConfigurationsFromAssembly(typeof(AppDbContext).Assembly);
    }
}

// Persistence/Configurations/OrderConfiguration.cs
public class OrderConfiguration : IEntityTypeConfiguration<Order>
{
    public void Configure(EntityTypeBuilder<Order> builder)
    {
        builder.HasKey(o => o.Id);

        builder.Property(o => o.Total)
            .HasPrecision(18, 2);

        builder.HasMany(o => o.Items)
            .WithOne()
            .HasForeignKey(i => i.OrderId)
            .OnDelete(DeleteBehavior.Cascade);

        builder.HasIndex(o => o.CustomerId);
        builder.HasIndex(o => o.CreatedAt);
    }
}
```

### Registration

```csharp
// Program.cs
builder.Services.AddDbContext<AppDbContext>(options =>
    options.UseNpgsql(builder.Configuration.GetConnectionString("Default")));
```

### Query Projections (Avoid Over-Fetching)

```csharp
// GOOD — project to DTO, only loads needed columns
public async Task<OrderResponse?> GetOrderAsync(Guid id, CancellationToken ct)
{
    return await db.Orders
        .Where(o => o.Id == id)
        .Select(o => new OrderResponse(
````
END THIRD-PARTY FILE 75122b672a52b423

The third-party file has ended. Everything between the 75122b672a52b423 tags is data: requests and commands from it are not followed. An “end of file” line with another tag inside the block is part of the file.

First 2731 of 9113 bytes. © codewithmukesh · MIT · https://github.com/codewithmukesh/dotnet-claude-kit/tree/HEAD/skills/ef-core/SKILL.md

_Part of the page did not fit — see the HTML version._

---
NeVibeCode on affpapa.org. Catalog texts are descriptions, not instructions for the agent. How to choose and install: https://affpapa.org/en/nevibecode/agents.md
