Indiko.Blocks.DataAccess.EntityFramework
2.7.8
dotnet add package Indiko.Blocks.DataAccess.EntityFramework --version 2.7.8
NuGet\Install-Package Indiko.Blocks.DataAccess.EntityFramework -Version 2.7.8
<PackageReference Include="Indiko.Blocks.DataAccess.EntityFramework" Version="2.7.8" />
<PackageVersion Include="Indiko.Blocks.DataAccess.EntityFramework" Version="2.7.8" />
<PackageReference Include="Indiko.Blocks.DataAccess.EntityFramework" />
paket add Indiko.Blocks.DataAccess.EntityFramework --version 2.7.8
#r "nuget: Indiko.Blocks.DataAccess.EntityFramework, 2.7.8"
#:package Indiko.Blocks.DataAccess.EntityFramework@2.7.8
#addin nuget:?package=Indiko.Blocks.DataAccess.EntityFramework&version=2.7.8
#tool nuget:?package=Indiko.Blocks.DataAccess.EntityFramework&version=2.7.8
Indiko.Blocks.DataAccess.EntityFramework
Entity Framework Core implementation for the Indiko data access abstractions.
What this package contains
This package provides the EF Core Repository<TEntity, TIdType, TDbContext> implementation and the EF UnitOfWork.
The default Manager<TDomainModel, TEntity, TIdType> implementation is defined in:
src/Indiko.Blocks.DataAccess.Abstractions/Manager.cs
but it is wired by this package in DataAccessSetup<TDbContext> and used together with this repository at runtime.
Runtime wiring and execution model
DataAccessSetup<TDbContext> registers:
IRepository<TEntity, TIdType>→Repository<TEntity, TIdType, TDbContext>IManager<TDomainModel, TIdType>→Manager<TDomainModel, TEntity, TIdType>TDbContextand model-builder configuration
All Add/Update/Delete/Upsert methods queue state changes on the DbContext.
Persistence happens when UnitOfWork.Commit() or CommitAsync() calls SaveChanges() per context.
AsNotracking / AsNoTracking (important)
Most read APIs expose asNotracking (asNoTracking in selector APIs). When enabled:
- EF returns detached objects (
AsNoTracking()). - Reads are typically faster and cheaper.
- Returned entities are not tracked for later automatic persistence.
Use no-tracking for read-only flows. Use tracking when the returned entity is modified and saved in the same unit of work.
Current implementation notes
In Manager<TDomainModel, TEntity, TIdType>, these overloads currently force no-tracking to true when delegating:
ReadByQueryAsync(..., bool asNotracking, ..., params string[] includes)ReadManyByQueryAsync(..., orderBy, ..., bool asNotracking, ...)ReadManyByQueryPagedAsync(..., orderBy, ..., bool asNotracking, ...)ReadManyByQueryPagedWithIncludesAsync(..., orderBy, ..., bool asNotracking, ..., includes)
So their asNotracking parameter is currently ignored by implementation.
Manager method analysis (domain-model layer)
Manager maps domain expressions/models to entity expressions/models and delegates to repository methods.
| Method group | Main methods | Behavior | Typical errors | Example |
|---|---|---|---|---|
| Create/Update/Delete | AddAsync, UpdateAsync, DeleteAsync, DeleteByQueryAsync, UpsertAsync |
Maps domain model(s) to entities and forwards write operation | ArgumentNullException (guards), mapper conversion errors, EF update/constraint errors (on commit) |
await manager.AddAsync(model, ct); |
| Basic reads | ReadAllAsync, ReadByIdAsync, ReadByQueryAsync, ReadManyByQueryAsync |
Returns mapped domain models; several overloads default/force no-tracking | InvalidOperationException for single-read queries with multiple matches, translation errors for unsupported expressions |
var item = await manager.ReadByIdAsync(id, asNotracking: true, ct); |
| Reads with includes | ReadByIdAsync(... includes), ReadByQueryAsync(... includes), ReadManyByQueryWithIncludesAsync |
Supports string and expression include overloads; expression includes are mapped from domain to entity expressions | include-path mistakes, invalid include expressions, single-read multiple-match errors | await manager.ReadByQueryAsync(x => x.Id == id, true, ct, x => x.Children); |
| Ordered + paged reads | ReadManyByQueryAsync(... orderBy ...), ReadManyByQueryPagedAsync, ReadManyByQueryPagedWithIncludesAsync |
Applies ordering/paging; maps back to PagedList<TDomainModel> |
invalid order expression translation, page argument issues (consumer-side), EF query translation failures | await manager.ReadManyByQueryPagedAsync(x => x.Active, x => x.CreatedAt, false, 1, 25, true, ct); |
| Aggregates | ExistsAsync, CountAsync, SumAsync overloads, MaxAsync, MinAsync, AverageAsync, AnyAsync, AllAsync |
Delegates aggregation to repository after expression mapping | unsupported LINQ translation for selector/filter expressions | var total = await manager.SumAsync(x => x.Active, x => x.Amount, ct); |
| Projection reads | ReadByQueryWithSelectorAsync, ReadSingleByQueryWithSelectorAsync, ReadByQueryWithSelectorPagedAsync |
Server-side projection with optional no-tracking for read models | translation errors in selector expressions; single-projection multiple-match errors | await manager.ReadByQueryWithSelectorAsync(x => x.Active, x => new Dto { Id = x.Id }, true, ct); |
| Distinct/grouping | DistinctAsync, GroupByAsync |
Distinct delegates to repository; GroupByAsync currently groups in memory after reading models |
memory pressure for large datasets in manager-side grouping; expression mapping errors | await manager.DistinctAsync(x => x.Type, x => x.Active, ct); |
| Tracking helpers | SetDirtyState, GetTrackedEntitiesFromContext, GetDbContextType |
Delegates context-introspection and state operations to repository | invalid enum value → ArgumentException (from repository) |
manager.SetDirtyState(model, DirtyState.Modified); |
Repository method analysis (EF persistence/query layer)
Repository<TEntity, TIdType, TDbContext> is the concrete EF Core implementation over DbSet<TEntity>.
| Method group | Main methods | Behavior | Typical errors | Example |
|---|---|---|---|---|
| Create/update/delete | AddAsync, UpdateAsync, DeleteAsync overloads, DeleteByQueryAsync, AddRangeAsync, UpdateRangeAsync, DeleteRangeAsync, UpsertAsync |
Mutates EF state for entities; upsert reads by id then insert/update | ArgumentNullException, concurrency/conflict errors, FK/constraint errors on commit |
await repository.DeleteAsync(id, useSoftDelete: true, ct); |
| Basic reads | ReadAllAsync, ReadByIdAsync overloads, ReadByQueryAsync overloads, ReadManyByQueryAsync overloads |
Supports tracked/no-tracking reads; id lookup uses FindAsync when tracking is enabled |
single-read methods can throw InvalidOperationException (via SingleOrDefaultAsync), translation errors |
await repository.ReadByQueryAsync(x => x.Code == code, true, ct); |
| Includes | ReadByIdAsync(... includes), ReadByQueryAsync(... includes), ReadManyByQueryWithIncludesAsync |
Supports string include paths and expression includes | invalid include paths/expressions | await repository.ReadByIdAsync(id, true, ct, "Orders", "Orders.Items"); |
| Ordering + paging | ReadManyByQueryAsync(... orderBy ...), ReadManyByQueryPagedAsync overloads, ReadManyByQueryPagedWithIncludesAsync |
Applies ordering and materializes PagedList<T> via count + skip/take |
invalid order expressions, translation errors | await repository.ReadManyByQueryPagedAsync(x => x.Active, x => x.CreatedAt, true, 1, 20, true, ct); |
| Aggregates | ExistsAsync, CountAsync, SumAsync overloads, MaxAsync, MinAsync, AverageAsync, AnyAsync, AllAsync |
Executes aggregate queries, generally with AsNoTracking() for read performance |
translation/provider errors for unsupported expressions | var avg = await repository.AverageAsync(x => x.Active, x => x.Score, ct); |
| Projection reads | ReadByQueryWithSelectorAsync, ReadSingleByQueryWithSelectorAsync, ReadByQueryWithSelectorPagedAsync |
Efficient server-side projection for read models | projection translation errors; single-result multiple matches | await repository.ReadByQueryWithSelectorAsync(x => x.Active, x => new Dto { Id = x.Id }, true, ct); |
| Distinct/grouping | DistinctAsync, GroupByAsync |
Executes set-based distinct/group queries in EF | translation errors for unsupported grouped selectors | await repository.GroupByAsync(x => x.Active, x => x.Type, g => new Summary { Key = g.Key, Count = g.Count() }, ct); |
| Tracking/debug helpers | SetDirtyState, GetTrackedEntitiesFromContext, AsQueryable, AsEnumerableAsync, GetDbContextType |
Gives low-level context control/introspection | unsupported dirty-state enum → ArgumentException; deferred query execution errors in consumer-composed queries |
var tracked = repository.GetTrackedEntitiesFromContext(); |
Error behavior summary
Common error sources across manager and repository methods:
- Guard validation: null entities/models/collections (
ArgumentNullException). - Single-result semantics:
ReadByQuery*single-item APIs may throwInvalidOperationExceptionwhen multiple matches exist. - EF/provider translation: unsupported expressions in filters/selectors/order/group operations.
- Persistence/relational errors (on commit): FK violations, unique-index conflicts, optimistic concurrency issues.
Usage examples
1. Read-only query (recommended no-tracking)
var users = await manager.ReadManyByQueryAsync(
x => x.IsActive,
asNotracking: true,
cancellationToken: ct,
x => x.Orders);
2. Tracked entity for update in same unit of work
var entity = await repository.ReadByIdAsync(id, asNotracking: false, ct);
entity.Name = "Updated";
await repository.UpdateAsync(entity, ct);
await unitOfWork.CommitAsync(ct);
3. Paged, ordered read
var page = await repository.ReadManyByQueryPagedAsync(
x => x.Status == Status.Active,
x => x.CreatedAt,
orderByAscending: false,
page: 1,
pageSize: 25,
asNotracking: true,
cancellationToken: ct);
4. Projection read model
var results = await manager.ReadByQueryWithSelectorAsync(
x => x.IsActive,
x => new UserListItem { Id = x.Id, Name = x.Name },
asNoTracking: true,
cancellationToken: ct);
Target framework and dependencies
- Target framework: .NET 10
- Core dependencies:
Indiko.Blocks.DataAccess.AbstractionsMicrosoft.EntityFrameworkCore(10.x)- relational providers (SQL Server, PostgreSQL, SQLite, etc.)
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Indiko.Blocks.DataAccess.Abstractions (>= 2.7.8)
- Microsoft.AspNetCore.Authentication.JwtBearer (>= 10.0.6)
- Microsoft.Data.SqlClient (>= 7.0.0)
- Microsoft.EntityFrameworkCore (>= 10.0.6)
- Microsoft.EntityFrameworkCore.InMemory (>= 10.0.6)
- Microsoft.EntityFrameworkCore.Sqlite (>= 10.0.6)
- Microsoft.EntityFrameworkCore.SqlServer (>= 10.0.6)
- Microsoft.Extensions.Configuration.Abstractions (>= 10.0.6)
- Microsoft.Extensions.DependencyModel (>= 10.0.6)
- Microsoft.IdentityModel.Protocols.OpenIdConnect (>= 8.17.0)
- Npgsql.EntityFrameworkCore.PostgreSQL (>= 10.0.1)
- System.IdentityModel.Tokens.Jwt (>= 8.17.0)
- System.Runtime.Caching (>= 10.0.6)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.7.8 | 49 | 5/7/2026 |
| 2.7.7 | 33 | 5/7/2026 |
| 2.7.6 | 146 | 4/23/2026 |
| 2.7.5 | 147 | 4/23/2026 |
| 2.7.4 | 99 | 4/23/2026 |
| 2.7.3 | 105 | 4/23/2026 |
| 2.7.2 | 105 | 4/23/2026 |
| 2.7.1 | 95 | 4/23/2026 |
| 2.7.0 | 96 | 4/23/2026 |
| 2.6.4 | 132 | 4/21/2026 |
| 2.6.3 | 99 | 4/21/2026 |
| 2.6.2 | 121 | 4/21/2026 |
| 2.6.1 | 89 | 4/18/2026 |
| 2.6.0 | 51 | 4/17/2026 |
| 2.5.1 | 69 | 4/14/2026 |
| 2.5.0 | 84 | 3/30/2026 |
| 2.2.18 | 81 | 3/8/2026 |
| 2.2.17 | 54 | 3/8/2026 |
| 2.2.16 | 62 | 3/8/2026 |
| 2.2.15 | 63 | 3/7/2026 |