What is Caerius.NET?
Caerius.NET is a focused, high‑performance Micro‑ORM for C# 13 / .NET 10 that turns SQL Server Stored Procedure results into strongly typed C# DTOs — in microseconds. It is built for teams who favor SQL Server and Stored Procedures for data access and want compile‑time safety, predictable performance, and a minimal API surface.
We are unapologetically specialized: Caerius.NET targets C# and Microsoft SQL Server. This clarity lets us optimize deeply for T/SQL, SqlDataReader, and SQL Server features such as Table‑Valued Parameters (TVP) and multi‑result sets.
Why Caerius.NET?
1. Performance you can feel
Caerius.NET is engineered to keep the hot path hot:
- Ordinal, allocation‑aware mapping: DTOs implement
ISpMapper<T>(or are source‑generated), reading columns by index for zero name lookups. - Compiler‑guided optimizations: extensive use of
MethodImplOptions.AggressiveOptimization/AggressiveInliningon hot methods. - Low‑level buffers and spans:
CollectionsMarshal.SetCount+CollectionsMarshal.AsSpan(list)to add items with minimal overhead.ArrayPool<T>.Sharedto rent/return buffers and buildImmutableArray<T>without extra copies.CommandBehavior.SequentialAccesson readers to stream rows efficiently.
- Right‑sized collections: you declare an expected capacity per call; Caerius.NET pre‑allocates to avoid list resizing.
- Caching tiers built‑in: Frozen (immutable in‑process), In‑Memory (expirable), and Redis (distributed) — enabled per call via the builder.
In short: no runtime reflection for mapping, no dynamic expression compilation on the hot path, and minimal allocations.
2. Source‑generated DTO and TVP mappers
[GenerateDto]emits a compile‑timeISpMapper<T>for your sealed partial records/classes. You get static, ordinal mapping with correct nullability and types.[GenerateTvp]emits anITvpMapper<T>so you can pass large sets as TVPs without writing boilerplateDataTablecode.
Prefer manual control? You can still implement ISpMapper<T> / ITvpMapper<T> yourself.
3. SQL Server expertise, not a kitchen sink
- Stored Procedures first. TVP, multi‑result sets, scalar reads, and write commands (
ExecuteNonQueryAsync,ExecuteScalarAsync, fire‑and‑forgetExecuteAsync). - Fluent parameter builder with TVP support:
StoredProcedureParametersBuildercomposes parameters and caching for each call. - Works great in existing databases that already standardize on Stored Procedures.
4. Simplicity and developer experience
- Small API surface: one builder, one
DbContextabstraction, and a handful of query/command methods. - Async‑only I/O by design to avoid accidental thread pool starvation and to play well with any SP duration.
- First‑class DI and Aspire integration: configure SQL Server and Redis via
CaeriusNetBuilder(manual or Aspire‑style).
5. Reliability and observability
- Clear exception boundaries: SQL errors are wrapped in
CaeriusNetSqlExceptionwith the originalSqlExceptionpreserved. - Structured logging hooks: plug your logger (e.g.,
ILogger) to trace connections, caching, and Redis activity. - Unit‑tested core and deterministic mapping semantics.
Core capabilities at a glance
- Stored Procedure to DTO mapping with compile‑time safety (
ISpMapper<T>/[GenerateDto]). - High‑throughput reads into
IEnumerable<T>,ReadOnlyCollection<T>, orImmutableArray<T>— pick what fits your scenario. - Multiple result sets in a single round‑trip (2 to 5 result sets helpers).
- TVP (Table‑Valued Parameters) support with
[GenerateTvp]for bulk‑style inputs. - Per‑call caching: Frozen, In‑Memory (TTL), or Redis distributed.
- Write commands:
ExecuteNonQueryAsync,ExecuteScalarAsync<T>, andExecuteAsync. - DI/Aspire friendly setup via
CaeriusNetBuilder.
When should you use Caerius.NET?
Use Caerius.NET when:
- Your team embraces SQL Server Stored Procedures for reads and writes.
- Latency and allocation budget matter — you want predictable, fast mapping and minimal runtime overhead.
- You need to push large parameter sets (IDs, GUIDs, composite keys) via TVPs.
- You operate in services where per‑call caching (including Redis) can offload the database.
- You prefer versioned SQL and stable DTOs over runtime query generation.
It may not be the best fit when you require ORM features such as change tracking, LINQ query translation, or multi‑database portability.
How does it compare?
- EF Core: feature‑rich ORM with change tracking and LINQ translation. Caerius.NET is leaner, SP‑centric, and typically faster on read paths due to ordinal mapping and fewer allocations.
- Dapper: excellent general‑purpose micro‑ORM. Caerius.NET optimizes specifically for SQL Server Stored Procedures, adds compile‑time DTO/TVP generators, multi‑result helpers, and per‑call caching primitives.
Choose the tool that matches your architecture — Caerius.NET excels when SPs, TVPs, and throughput are central.
Architecture and hot path (simplified)
- You build call settings with
StoredProcedureParametersBuilder(schema, SP name, capacity, parameters, optional cache). - Read commands open a connection via
ICaeriusNetDbContext.DbConnection()and execute withSqlCommandusingSequentialAccess. - Rows are mapped by
ISpMapper<T>(manual or generated) with ordinal reads (e.g.,GetInt32(0)). - Results are materialized using pre‑sized collections and pooling helpers; optional cache is read/written via chosen backend.
Example: one SP, one cache, zero fuss
var sp = new StoredProcedureParametersBuilder("Users", "usp_Get_All_Users", 250)
.AddFrozenCache("users:all:frozen")
.Build();
var users = await dbContext.QueryAsReadOnlyCollectionAsync<UserDto>(sp, cancellationToken);With TVP and Redis:
var sp = new StoredProcedureParametersBuilder("dbo", "sp_GetUsers_By_Tvp_Ids_And_Age", 1024)
.AddTvpParameter("Ids", tvpItems)
.AddParameter("Age", age, SqlDbType.Int)
.AddRedisCache($"users:age:{age}", TimeSpan.FromMinutes(2))
.Build();
var (adults, seniors) = await dbContext
.QueryMultipleIEnumerableAsync<UserDto, UserDto>(sp, cancellationToken);Benchmarks and realism
We publish micro‑benchmarks that focus on the mapping and materialization path. As always, measure in your environment — network, SQL plans, and payload size dominate end‑to‑end latency. Caerius.NET minimizes client‑side costs so your time is spent where it matters: on the database.
Learn more
- Quickstart: Getting Started
- Deep dive: Advanced Usage
- Caching strategies: Caching
- Practices that scale: Best Practices
- Full surface: API Reference
