agentleFS
zdanovichnickzdanovichnick/dotnet-pilot/skills/ef-core-patterns/SKILL.md

ef-core-patterns

Skill5 starsChanged 6 days agoMITView on GitHub

EF Core best practices reference — safe migrations, query optimization, configuration patterns, and common pitfalls.

1 other project uses a version of this.

Adopted by

Most recently taken up by

The file

Show its rules and text

We split this skill into the rules it gives an agent

13 rules. About 0 are common, 3 are distinctive, and 10 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈3

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 10

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Never hand-write a migration from scratch — the model snapshot would drift

    line 31
  2. Distinctive:

    Keep migrations small and reversible

    line 36
  3. Very specific:

    Use migrationBuilder.Sql() for data migrations, not EF operations

    line 37
  4. Very specific:

    Use AsNoTracking() for read-only queries

    line 64
  5. Very specific:

    Use projections (Select) to fetch only needed columns

    line 65
  6. Very specific:

    Use Include with ThenInclude for eager loading (avoid N+1)

    line 66
  7. Very specific:

    Use split queries for many includes: .AsSplitQuery()

    line 67
  8. Very specific:

    Use ExecuteUpdateAsync / ExecuteDeleteAsync for bulk operations (EF 7+)

    line 68
  9. Very specific:

    Don't call ToList() before filtering (materializes entire table)

    line 71
  10. Very specific:

    Don't use Count() when you need Any()

    line 72
  11. Distinctive:

    Don't load navigation properties you don't need

    line 73
  12. Very specific:

    Don't use FromSqlRaw with string interpolation (SQL injection risk)

    line 74
  13. Very specific:

    Don't forget CancellationToken on async queries

    line 75

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

EF Core Patterns

Reference material for EF Core development.

Migration Safety

Safe Operations

  • Adding a new table
  • Adding a nullable column
  • Adding a column with a default value
  • Adding an index
  • Renaming (with migrationBuilder.RenameColumn — preserves data)

Dangerous Operations (require confirmation)

  • Dropping a column (data loss)
  • Changing column type (potential data truncation)
  • Adding NOT NULL column without default (fails on existing rows)
  • Dropping a table (data loss)
  • Removing an index (performance impact)

Migration Best Practices

  • One migration per logical change
  • Generate with dotnet ef migrations add, then review and adjust the generated Up/Down (a rename scaffolded as drop + add must become RenameColumn; data moves go in Sql()). Never hand-write a migration from scratch — the model snapshot would drift
  • dotnet ef database update has no dry-run: review the SQL with dotnet ef migrations script <from> <to> (--idempotent for scripts run against unknown state)
  • dotnet ef migrations has-pending-model-changes (EF Core 8+) fails when the model has changed since the last migration — use it as a CI gate
  • Keep migrations small and reversible
  • Use migrationBuilder.Sql() for data migrations, not EF operations

Configuration Patterns

Fluent API (preferred)

public class UserConfiguration : IEntityTypeConfiguration<User>
{
    public void Configure(EntityTypeBuilder<User> builder)
    {
        builder.HasKey(u => u.Id);
        builder.Property(u => u.Email).HasMaxLength(256).IsRequired();
        builder.HasIndex(u => u.Email).IsUnique();
        builder.HasMany(u => u.Orders).WithOne(o => o.User).HasForeignKey(o => o.UserId);
    }
}

DbContext Registration

// In OnModelCreating:
modelBuilder.ApplyConfigurationsFromAssembly(typeof(ApplicationDbContext).Assembly);

Query Optimization

Do

  • Use AsNoTracking() for read-only queries
  • Use projections (Select) to fetch only needed columns
  • Use Include with ThenInclude for eager loading (avoid N+1)
  • Use split queries for many includes: .AsSplitQuery()
  • Use ExecuteUpdateAsync / ExecuteDeleteAsync for bulk operations (EF 7+)

Don't

  • Don't call ToList() before filtering (materializes entire table)
  • Don't use Count() when you need Any()
  • Don't load navigation properties you don't need
  • Don't use FromSqlRaw with string interpolation (SQL injection risk)
  • Don't forget CancellationToken on async queries

See Also

  • skills/ddd/SKILL.md — value converters and complex properties for DDD entities
  • skills/testing-dotnet/SKILL.md — testing queries against the real provider

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.