data-access-ef-core
Skill1 starsChanged 6 days agoMITView on GitHub
How the repository reads and writes the SQLite database with EF Core - scoped DbContext, no tracking by default, SQL projections for lists, set-based updates and deletes, and safe LIKE searches. Use when adding or changing a repository method or a query.
In this repository40 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- add-a-use-caseSkill
- api-conventionsSkill
- branches-and-pull-requestsSkill
- cancellationSkill
- ci-for-your-solutionSkill
- ci-pipelineSkill
- clean-architecture-layersSkill
- configuration-and-environmentsSkill
- coverageSkill
- csharp-house-styleSkill
- database-migrationsSkill
- docker-and-composeSkill
- docs-and-voiceSkill
- errors-and-exceptionsSkill
- expose-a-use-caseSkill
- family-syncSkill
- health-checksSkill
- integration-testsSkill
- json-serializationSkill
- mapping-with-mapperlySkill
- mcp-inspectorSkill
- mediatorSkill
- optional-token-authSkill
- packages-and-dependenciesSkill
- pagingSkill
- presentation-integration-testsSkill
- releasesSkill
- sample-dataSkill
- security-findingsSkill
- serilogSkill
- telemetrySkill
- template-authoringSkill
- test-designSkill
- time-providerSkill
- unit-testsSkill
- validationSkill
- writing-a-skillSkill
- xml-docs-and-openapiSkill
The file
We split this skill into the rules it gives an agent
7 rules. About 0 are common, 0 are distinctive, and 7 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
7
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 16
Add the method to the Application interface first (IMoviesRepository and friends), taking a CancellationToken last.
- Very specific: line 25
Don't check first. The handler turns null or false into NotFoundException (errors-and-exceptions).
- Very specific: line 28
Add repository tests (integration-tests).
- Very specific: line 63
Use string.Contains(value, StringComparison.OrdinalIgnoreCase) in a query.
- Very specific: line 64
Use DateTime.UtcNow. Use the injected TimeProvider so tests can fix the clock.
- Very specific: line 67
Add AsNoTracking() to a query.
- Very specific: line 68
Call an Exists method before an update or delete.
≈ “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.
Files
Data access with EF Core
The rule
One repository, EntityFrameworkMovieReviewsRepository in src/Infrastructure/Databases/MovieReviews/, implements every repository interface from Application. It and MovieReviewsDbContext are scoped: one per request, never shared between threads. The context doesn't track queries (QueryTrackingBehavior.NoTracking in AddInfrastructure), because nothing loads an entity to change it. Lists are projected in SQL. Updates and deletes are set-based and are their own existence check. The repository returns Application entities, never database models.
Steps
- Add the method to the Application interface first (
IMoviesRepositoryand friends), taking aCancellationTokenlast. - Implement it in the matching
#regionof the repository, aspublic async Task<...>like every other method. - Reads: start from
this.context.<Set>, filter, then either- a list: take a
PageRequest page, count, order (ending with the id),Skip(page.Offset),Take(page.Limit),Selectthe summary fields so SQL does the counting and averaging, and returnnew Page<T>(items, page.Offset, page.Limit, totalCount)(paging), or - one entity:
Includewhat the entity needs,FirstOrDefaultAsync, then map withthis.mapper.ToDomain(...)(mapping-with-mapperly).
- a list: take a
- Writes:
- create: build the model, set
DateCreatedandDateModifiedfromthis.timeProvider.GetUtcNow().UtcDateTime,Add,SaveChangesAsync, then read it back with its includes. - update:
Where(...).ExecuteUpdateAsync(setters => ...), always settingDateModified. No rows changed means not found, so returnnull; otherwise read the entity back and return it. - delete:
Where(...).ExecuteDeleteAsync(...), returning whether a row was deleted. - Don't check first. The handler turns
nullorfalseintoNotFoundException(errors-and-exceptions). - New rows get a version 7 GUID from
Version7GuidValueGenerator, set up for every model inEntityConfiguration<T>. Each model needs its own configuration class, even an empty one, or it gets random GUIDs.
- create: build the model, set
- Text search uses
EF.Functions.Likewith theContainsPatternhelper, which escapes%,_and\. - Add repository tests (
integration-tests).
Example
// src/Infrastructure/Databases/MovieReviews/EntityFrameworkMovieReviewsRepository.cs
public async Task<ApplicationReview?> UpdateReview(Guid id, int stars, CancellationToken cancellationToken)
{
var now = this.timeProvider.GetUtcNow().UtcDateTime;
// The update is the existence check: no rows changed means there's no such review.
var updated = await this.context.Reviews
.Where(r => r.Id == id)
.ExecuteUpdateAsync(
setters => setters
.SetProperty(r => r.Stars, stars)
.SetProperty(r => r.DateModified, now),
cancellationToken);
return updated == 0 ? null : await this.GetReviewById(id, cancellationToken);
}if (!string.IsNullOrWhiteSpace(query))
{
var pattern = ContainsPattern(query);
movies = movies.Where(m => EF.Functions.Like(m.Title, pattern, EscapeCharacter));
}Don't
- Register the
DbContextor repository as a singleton. A shared context fails under concurrent requests. - Use
string.Contains(value, StringComparison.OrdinalIgnoreCase)in a query. EF Core can't translate it; use theLIKEhelper. - Use
DateTime.UtcNow. Use the injectedTimeProviderso tests can fix the clock. Includechildren on a list query to count them.- Load an entity, change it and
SaveChangesto update one column. UseExecuteUpdateAsync. - Add
AsNoTracking()to a query. It's already the default. - Call an
Existsmethod before an update or delete. - Return a database model or
IQueryablefrom the repository.
Check
dotnet test tests/Infrastructure.Tests.IntegrationDoes 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
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.

