Documentation Index
Fetch the complete documentation index at: https://mintlify.com/Orbis25/FoundationKit/llms.txt
Use this file to discover all available pages before exploring further.
MapRepository is the abstract base class to use when your application follows the DTO pattern and you want the repository layer to own all mapping concerns. Unlike BaseRepository, which works exclusively with raw EF Core entity types, MapRepository accepts typed input DTOs for writes and automatically projects entity queries to output DTOs at the database level using AutoMapper’s ProjectTo. This means your controllers and services only ever see DTOs — entity types are confined to the repository and the EF Core DbContext.
Choose MapRepository over BaseRepository when:
- Your API surface exposes DTOs that differ structurally from the database entity (e.g., flattened navigation properties, computed fields, or hidden audit columns).
- You want
SELECTstatements to include only the columns your DTO needs, reducing data transfer. - You want a single AutoMapper profile to serve as the canonical mapping definition for both reads and writes.
Class Signature
| Type Parameter | Constraint | Role |
|---|---|---|
TContext | DbContext | Your application’s EF Core context |
TEntity | BaseModel | The database entity class |
TInputModel | BaseInput | DTO for create operations |
TEditModel | BaseEdit | DTO for update operations |
TDtoModel | BaseOutput | Read-side DTO returned by all queries |
Constructor
The EF Core
DbContext instance. Stored privately; subclasses interact with the database exclusively through the base class methods.An AutoMapper
IMapper instance. Used for TInputModel → TEntity, TEditModel → TEntity, and TEntity → TDtoModel mappings, as well as the reverse TDtoModel → TEntity mapping needed by SoftRemove and Remove.Method Implementations
GetAll — Query-Level DTO Projection
GetAll is the foundation of every read method. It calls ProjectTo<TDtoModel>(_mapper.ConfigurationProvider) on the raw entity DbSet, converting the LINQ expression tree into a SQL SELECT that only fetches the columns your DTO maps to. No intermediate entity objects are materialised in memory.
ProjectTo, expressions are written against TDtoModel properties, not entity properties. Ensure your AutoMapper profile maps every property your filter or sort expressions reference.
GetPaginatedList
CallsGetAll to build the filtered, ordered query, then applies Skip/Take based on Paginate.Page and Paginate.Qyt.
Pagination settings:
Page, Qyt (items per page), OrderByDesc, and NoPaginate.Optional filter predicate applied before Skip/Take.
Optional DTO property selector for ordering. Falls back to
CreatedAt when null.Propagates cancellation.
Navigation-property selectors for eager loading.
Contains
ActualPage, Qyt, PageTotal, Total, and Results (IReadOnlyCollection<TDtoModel>).GetList
Delegates toGetAll and materialises the result with ToListAsync.
Optional filter predicate. Pass
null to retrieve all rows.true for descending order; false for ascending.Optional sort-property selector.
Propagates cancellation.
Navigation properties for eager loading.
A fully materialised, in-memory collection of projected DTOs.
GetById
Projects the entityDbSet to TDtoModel via ProjectTo, then executes FirstOrDefaultAsync for the given Id.
Primary key of the record to fetch.
When
true, the query is executed with AsNoTracking().Propagates cancellation.
Navigation properties to include on the projected DTO query.
The projected DTO, or
null if no record with the given Id exists.GetOneAsync
Returns the first projectedTDtoModel matching the predicate, using FirstOrDefaultAsync on the ProjectTo query.
Filter predicate applied to the projected DTO query.
Propagates cancellation.
The first matching DTO, or
null.Create — Input DTO to Entity to Output DTO
- Maps
TInputModel→TEntityvia_mapper.Map. - Adds the entity to the
DbSetand commits within a transaction. - Maps the persisted entity (now with its database-assigned
Id,CreatedAt, etc.) back toTDtoModelfor the response.
Update — Audit-Preserving Entity Update
Two overloads are available. The full overload exposes theverifyEntity flag; the convenience overload omits it and delegates to the full one with verifyEntity: false.
verifyEntity == true:
- Calls
GetById(model.Id, asNotTraking: true)to fetch the current DTO. - Copies
CreatedByandCreatedAtfrom the existing DTO ontomodelto prevent accidental overwrite of immutable audit fields. - Maps
TEditModel→TEntityand callsUpdate+CommitAsync. - Maps the updated entity back to
TDtoModel.
null immediately when verifyEntity is true and no record with the given Id exists.
Exist
Returns whether any projectedTDtoModel matches the predicate. When expression is null, returns false (unlike IBaseRepository.ExistAsync, which returns true for any row when the expression is null).
Filter predicate. When
null, the method returns false.Propagates cancellation.
true when at least one projected DTO matches the expression; false otherwise.Count
Chains zero or moreWhere predicates on the ProjectTo query and returns the row count.
Propagates cancellation.
Zero or more filter predicates (logical AND). Passing none counts all rows.
Row count satisfying all predicates.
SoftRemove — DTO-Mapped Logical Delete
MapRepository does not hold entity references after queries (all data is projected to DTOs), SoftRemove must map the DTO back to an entity before it can set IsDeleted = true. This means your AutoMapper profile must include a TDtoModel → TEntity reverse mapping.
Remove
Fetches the record as a DTO, maps it back to the entity, removes the entity, and commits.SoftRemove, this method requires a TDtoModel → TEntity reverse mapping in your AutoMapper profile. Returns false when no entity with the given Id exists.
GetEntities — Raw Entity Access
The extendedIMapRepository<T, ...> interface exposes GetEntities, which returns an IQueryable<TEntity> directly from the DbSet. Use this when you need entity-level data not available through the DTO projection.
The
expression parameter is accepted by the method signature but is not applied in the current implementation — the returned IQueryable is always unfiltered. Chain a .Where() call on the returned queryable to apply your predicate.UpdatePartialEntityAsync — Column-Level Partial Update
Uses EF Core’s change-tracker entry API to mark only listed properties asModified, generating a targeted UPDATE statement without fetching the current row.
CommitAsync
WrapsSaveChangesAsync in an explicit database transaction. On success the transaction is committed; on any exception the transaction is rolled back and a DbUpdateException is thrown.
CommitAsync is public and can be called directly when you have staged multiple mutations that must commit atomically. All of Create, Update, SoftRemove, and Remove call CommitAsync internally.
CommitAndResultAsync
Identical toCommitAsync but returns null on success or an error message string on failure instead of throwing. The transaction is still rolled back on error.
AutoMapper Profile Setup
EveryMapRepository subclass requires three mapping directions to be configured in AutoMapper: