Create or modify a CoreEx Infrastructure-layer repository. USE FOR: new repository class, adding CRUD operations, adding a custom query (QueryArgsConfig<TSelf>), bidirectional mapper (BiDirectionMapper), EfDb model accessor, Result<T> pipeline variants. DO NOT USE FOR: Application-layer service logic, domain invariants, typed HTTP clients/adapters (those follow adapter conventions in the infrastructure instructions, not this skill).
Scanned 8/31/2026
Install to Claude Code
npx -y skills add Avanade/CoreEx --skill coreex-repository --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Coreex Repository?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/avanade-coreex-repository)More formats (shields.io, HTML) on the badges page.
---
name: coreex-repository
description: "Create or modify a CoreEx Infrastructure-layer repository. USE FOR: new repository class, adding CRUD operations, adding a custom query (QueryArgsConfig<TSelf>), bidirectional mapper (BiDirectionMapper), EfDb model accessor, Result<T> pipeline variants. DO NOT USE FOR: Application-layer service logic, domain invariants, typed HTTP clients/adapters (those follow adapter conventions in the infrastructure instructions, not this skill)."
argument-hint: "Optional: entity name, database type (PostgreSQL/SQL Server), operations needed (get/create/update/delete/query), new or existing repository; for query: filtering (default: yes), ordering (default: yes), paging (default: yes), count support (default: no), then per filter field: name + property type + allowed operators + case-insensitive? + model mapping if different"
tags: ["repository", "infrastructure", "efcore", "mapping", "coreex", "data-access", "result"]
---
<!--
AI workflow asset — dual-audience notice:
- In the Avanade/CoreEx repository: this file is the authored source. Edit it here.
- In a consumer repository: this file was generated by `dotnet new coreex-ai` (or refreshed via
`dotnet new coreex-ai --force` / the `/coreex-docs-sync` skill). Do not hand-edit it directly —
propose the change upstream in Avanade/CoreEx instead, then refresh once it is released.
-->
# CoreEx: Repository
Guides you through creating or modifying a CoreEx Infrastructure-layer repository in `Infrastructure/Repositories/`. Covers CRUD delegates, custom queries, bidirectional mappers, EfDb accessors, and `Result<T>` pipelines.
## When to Use
- New repository class for an entity (scaffold, EfDb accessor, mapper, registration)
- Adding a CRUD operation (get/create/update/delete) using EfDb delegate shortcuts
- Adding a custom query method with `QueryArgsConfig` dynamic filtering/ordering
- Adding a `BiDirectionMapper` (Contract ↔ Persistence) in `Infrastructure/Mapping/`
- Adding or modifying an `EfDbMappedModel` or `EfDbModel` accessor on `*EfDb`
- Switching a method to the `Result<T>` / `*WithResultAsync` pipeline
## When Not to Use
- Application-layer service logic — inject the repository interface, do not modify it from Infrastructure
- Domain aggregates, entities, value objects — those belong in the Domain layer
- Persistence model class creation — those are generated by the `*.Database` tooling; run `dotnet run -- CodeGen` there
## Quick Reference
**Clarifying questions before writing any code:**
0. **Resolve from state first.** Read the solution-root `AGENTS.md` **Feature Configuration** for `data-provider` (SQL Server / PostgreSQL — gates this skill) and check whether a `*.Domain` project exists (Domain-mapping vs contract-mapping). Only ask for what is unresolved; re-state resolved values for confirmation.
1. Which entity? Which database type (PostgreSQL / SQL Server)? Check the project's `Program.cs`.
2. New repository or adding to an existing one?
3. Operations needed: Get / Create / Update / Delete / Query?
4. Does the project use `Result<T>` / ROP pipelines? (→ `*WithResultAsync` — per-project style choice, not tied to DDD)
5. Does the query need dynamic filtering/ordering? (→ `QueryArgsConfig<TSelf>`) — if yes, collect the **complete field list** from the developer before writing any code: for each filter field the name, property type, allowed operators, and model/LINQ name if it differs from the contract name; for each order-by field the name and whether it should be in the default sort or always appended. **AI cannot infer these from the entity shape.**
**Key rules at a glance:**
- `[ScopedService<IInterface>]` on every repository class — auto-registers in DI
- Primary constructor: `public class ProductRepository(ProductsEfDb ef) : IProductRepository`; guard with `ThrowIfNull()`
- Use EfDb delegate shortcuts (`GetAsync`, `CreateAsync`, `UpdateAsync`, `DeleteAsync`) — never write raw `DbContext` CRUD
- `DataResult<T>` return for Create/Update; `DataResult` for Delete — includes mutation flag for event decisions
- `*WithResultAsync` variants for `Result<T>` ROP pipelines (per-project style choice)
- `BiDirectionMapper`: override **both** `OnMap` overloads; map `Id` explicitly; **never** map `ETag` or `ChangeLog` — base mapper owns them
- `QueryArgsConfig<TSelf>`: create a dedicated `{Name}QueryArgsConfig : QueryArgsConfig<{Name}QueryArgsConfig>` class per entity in `Infrastructure/Repositories/`; access via `.Default`; call `.Parse(query).ThrowOnError()` before use — never instantiate per-request
- `AddReferenceDataField<TRef>(field, model, ...)`: `field` is always the contract's generated nav property (`{Name}`, never `{Name}Code`) — a fixed, documented source-generator convention, **not** something to verify by exploring generated code
- `ToMappedItemsResultAsync(mapper, paging, cancellationToken: cancellationToken)`: always pass `cancellationToken` **by name** — `autoCount` (`bool`, defaults `true`) sits before it in the signature, and a bare positional token there fails to compile
- Always `.ConfigureAwait(false)` on every `await`
For full workflow and code examples see [`references/workflow.md`](references/workflow.md).
## Key References
- [`/.github/instructions/coreex-repositories.instructions.md`](/.github/instructions/coreex-repositories.instructions.md) — full conventions: EfDb, DbContext, mappers, query config, adapters
- Related skills: [`coreex-db-migration`](../coreex-db-migration/SKILL.md) (generates the persistence models this maps), [`coreex-app-service`](../coreex-app-service/SKILL.md) + [`coreex-adapter`](../coreex-adapter/SKILL.md) (consumers), [`coreex-aggregate`](../coreex-aggregate/SKILL.md) (persisting aggregates)
- Illustrative examples (CoreEx sample — not present in your project):
- [contract-mapping repositories](https://github.com/Avanade/CoreEx/tree/main/samples/src/Contoso.Products.Infrastructure/Repositories) — `ProductRepository` (CRUD + query), `ProductsEfDb`, `ProductsDbContext` — and [BiDirectionMapper](https://github.com/Avanade/CoreEx/tree/main/samples/src/Contoso.Products.Infrastructure/Mapping) (`ProductMapper`)
- [Domain-mapping repositories](https://github.com/Avanade/CoreEx/tree/main/samples/src/Contoso.Shopping.Infrastructure/Repositories) — `BasketRepository` (`Result<T>` + Domain mapping) — and [one-way Domain ↔ Persistence mappers](https://github.com/Avanade/CoreEx/tree/main/samples/src/Contoso.Shopping.Infrastructure/Mapping) (`BasketMapper`)
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!