# dotnet-data Plugin: Data Access Skills for Entity Framework Core

> Master Entity Framework Core data access with the dotnet-data plugin. Learn to optimize EF Core queries by eliminating N+1 patterns, using AsNoTracking, and compiled queries.

- Repository: [.NET Platform/skills](https://github.com/dotnet/skills)
- Tags: how-to-guide
- Published: 2026-07-06

---

**The dotnet-data plugin currently provides one skill, `optimizing-ef-core-queries`, that teaches developers how to eliminate N+1 query patterns, apply `AsNoTracking` for read-only scenarios, and leverage compiled queries for high-performance Entity Framework Core data access.**

The dotnet-data plugin in the dotnet/skills repository delivers targeted guidance for improving Entity Framework Core (EF Core) performance through a standardized skill-based architecture. Located in `plugins/dotnet-data/`, this plugin follows the repository's skill-plugin pattern to expose data access best practices via markdown-based skill definitions.

## Plugin Architecture and Structure

The dotnet-data plugin adheres to the standard skill-plugin pattern used throughout the dotnet/skills repository. Its structure consists of a declaration file and skill-specific documentation that together expose optimization workflows to consuming tools.

### plugin.json Configuration

The [`plugin.json`](https://github.com/dotnet/skills/blob/main/plugin.json) file serves as the plugin's manifest, declaring the plugin name, version, description, and the path to the skills directory. Located at [`plugins/dotnet-data/plugin.json`](https://github.com/dotnet/skills/blob/main/plugins/dotnet-data/plugin.json), this file enables discovery tools to identify available data access capabilities without parsing individual skill implementations.

### Skill Definition Structure

Individual skills reside in the `plugins/dotnet-data/skills/` directory, each implemented as a self-contained Markdown file with front-matter headers. The `optimizing-ef-core-queries` skill is defined in [`plugins/dotnet-data/skills/optimizing-ef-core-queries/SKILL.md`](https://github.com/dotnet/skills/blob/main/plugins/dotnet-data/skills/optimizing-ef-core-queries/SKILL.md), which includes invocation triggers, required inputs, step-by-step workflows, validation checklists, and executable code snippets.

## The Optimizing EF Core Queries Skill

This skill provides a comprehensive workflow for diagnosing and resolving EF Core performance issues, specifically targeting query efficiency and database resource utilization.

### When to Apply This Skill

Invoke this skill when your application exhibits slow query execution, database CPU or IO spikes, or when logs reveal N+1 query patterns. It is particularly valuable when LINQ queries generate excessive SQL statements or when ORM inefficiency impacts production performance.

### Step-by-Step Optimization Workflow

The skill documentation in [`SKILL.md`](https://github.com/dotnet/skills/blob/main/SKILL.md) outlines a six-step optimization process:

1. **Enable detailed logging** to capture generated SQL and identify bottlenecks.
2. **Eliminate N+1 queries** through eager loading with `Include`, query splitting with `AsSplitQuery`, or projection techniques.
3. **Apply `AsNoTracking`** for read-only scenarios to disable change tracking overhead.
4. **Cache compiled queries** for frequently executed hot paths using `EF.CompileAsyncQuery`.
5. **Avoid common pitfalls** such as client-side evaluation or premature `ToList()` calls before filtering.
6. **Drop to raw SQL** using `FromSqlInterpolated` when LINQ cannot generate efficient database queries.

### Code Implementation Examples

The following examples demonstrate the core techniques described in the `optimizing-ef-core-queries` skill.

Enable EF Core query logging to diagnose performance issues:

```csharp
var optionsBuilder = new DbContextOptionsBuilder<AppDbContext>()
    .UseSqlServer(connectionString)
    .LogTo(Console.WriteLine, LogLevel.Information)
    .EnableSensitiveDataLogging()   // dev only!
    .EnableDetailedErrors();

```

Fix N+1 patterns by eager loading related entities:

```csharp
var orders = await db.Orders
    .Include(o => o.Items)          // single query with JOIN
    .AsSplitQuery()                // split into two queries when many children
    .ToListAsync();

```

Use `AsNoTracking` for read-only queries to improve performance:

```csharp
var products = await db.Products
    .AsNoTracking()                // disables change tracking
    .Where(p => p.IsActive)
    .ToListAsync();

```

Compile and cache hot-path queries to eliminate recompilation overhead:

```csharp
private static readonly Func<AppDbContext, int, Task<Order?>> GetOrderById =
    EF.CompileAsyncQuery((AppDbContext ctx, int id) =>
        ctx.Orders
           .Include(o => o.Items)
           .FirstOrDefault(o => o.Id == id));

var order = await GetOrderById(db, orderId);   // fast, no recompilation cost

```

Avoid inefficient counting by using `Any()` for existence checks:

```csharp
bool hasActiveUsers = await db.Users.AnyAsync(u => u.IsActive);

```

Execute parameterized raw SQL when LINQ cannot optimize the query:

```csharp
var results = await db.Orders
    .FromSqlInterpolated($@"
        SELECT o.* FROM Orders o
        INNER JOIN (
            SELECT OrderId, SUM(Price) AS Total
            FROM OrderItems
            GROUP BY OrderId
            HAVING SUM(Price) > {minTotal}
        ) t ON o.Id = t.OrderId")
    .AsNoTracking()
    .ToListAsync();

```

## Summary

The dotnet-data plugin provides a focused set of data access optimizations for Entity Framework Core:

- **Single skill focus**: Currently implements `optimizing-ef-core-queries` in [`plugins/dotnet-data/skills/optimizing-ef-core-queries/SKILL.md`](https://github.com/dotnet/skills/blob/main/plugins/dotnet-data/skills/optimizing-ef-core-queries/SKILL.md)
- **Performance-centric**: Targets N+1 queries, tracking overhead, and query compilation
- **Production-ready**: Includes logging strategies, raw SQL fallbacks, and validation checklists
- **Extensible architecture**: New skills can be added by creating additional subdirectories under `plugins/dotnet-data/skills/`

## Frequently Asked Questions

### What data access skills are included in the dotnet-data plugin?

The dotnet-data plugin currently contains one skill: `optimizing-ef-core-queries`. This skill provides a comprehensive guide to improving Entity Framework Core performance through query optimization techniques, tracking mode selection, and compiled query caching.

### How does the plugin structure support additional data access skills?

The plugin follows a modular architecture where [`plugin.json`](https://github.com/dotnet/skills/blob/main/plugin.json) declares the plugin metadata and points to the `skills/` directory. New skills can be added by creating new subdirectories under `plugins/dotnet-data/skills/`, each containing a [`SKILL.md`](https://github.com/dotnet/skills/blob/main/SKILL.md) file with front-matter headers and implementation guides.

### When should I use AsNoTracking versus standard query tracking?

Apply `AsNoTracking` for read-only scenarios where entities are not modified, such as display-only views or reporting queries. This reduces memory overhead and improves performance by disabling EF Core's change tracking mechanism. Use standard tracking when you need to update entities within the same context.

### Can I use raw SQL with the optimization techniques described?

Yes, the skill explicitly includes `FromSqlInterpolated` as a fallback when LINQ cannot generate efficient SQL. This approach allows parameterized raw SQL execution while maintaining connection to the EF Core context and combining with other LINQ operations like `AsNoTracking`.