CaeriusNet 11.0.0
See the version list below for details.
dotnet add package CaeriusNet --version 11.0.0
NuGet\Install-Package CaeriusNet -Version 11.0.0
<PackageReference Include="CaeriusNet" Version="11.0.0" />
<PackageVersion Include="CaeriusNet" Version="11.0.0" />
<PackageReference Include="CaeriusNet" />
paket add CaeriusNet --version 11.0.0
#r "nuget: CaeriusNet, 11.0.0"
#:package CaeriusNet@11.0.0
#addin nuget:?package=CaeriusNet&version=11.0.0
#tool nuget:?package=CaeriusNet&version=11.0.0
CaeriusNet
<p align="center"> <a href="https://www.nuget.org/packages/CaeriusNet"><img src="https://img.shields.io/nuget/v/CaeriusNet?style=flat&logo=nuget" alt="NuGet version"></a> <a href="https://www.nuget.org/packages/CaeriusNet"><img src="https://img.shields.io/nuget/dt/CaeriusNet?style=flat" alt="NuGet downloads"></a> <img src="https://img.shields.io/badge/.NET%2010-512BD4.svg?style=flat&logo=dotnet&logoColor=white" alt=".NET 10"> <img src="https://img.shields.io/badge/C%23%2014-%23239120.svg?style=flat&logo=csharp&logoColor=white" alt="C# 14"> <img src="https://img.shields.io/badge/license-MIT-blue.svg?style=flat" alt="MIT License"> </p>
High-performance micro-ORM for C# 14 / .NET 10 that executes SQL Server Stored Procedures, maps DTOs at compile-time, passes Table-Valued Parameters, and caches results — all in a single package, zero reflection at runtime.
Installation
dotnet add package CaeriusNet
Prerequisites
- .NET 10 or later
- SQL Server 2019 or later
Quick Start
1. Configure (Program.cs)
// Standard
CaeriusNetBuilder.Create(services)
.WithSqlServer("Server=.;Database=MyDb;Trusted_Connection=True;")
.Build();
// .NET Aspire
CaeriusNetBuilder.Create(builder)
.WithAspireSqlServer("CaeriusNet")
.WithAspireRedis()
.Build();
2. Define a DTO
Source-generated (recommended):
[GenerateDto]
public sealed partial record ProductDto(int Id, string Name, decimal Price);
// Generates: ISpMapper<ProductDto> with MapFromDataReader at compile-time
Manual:
public sealed record ProductDto(int Id, string Name, decimal Price) : ISpMapper<ProductDto>
{
public static ProductDto MapFromDataReader(SqlDataReader reader)
=> new(reader.GetInt32(0), reader.GetString(1), reader.GetDecimal(2));
}
3. Execute a Stored Procedure
var sp = new StoredProcedureParametersBuilder("dbo", "sp_GetProducts", capacity: 1)
.AddParameter("CategoryId", categoryId, SqlDbType.Int)
.Build();
ReadOnlyCollection<ProductDto> products =
await dbContext.QueryAsReadOnlyCollectionAsync<ProductDto>(sp, ct);
Table-Valued Parameters (TVP)
Source-generated:
[GenerateTvp(Schema = "dbo", TvpName = "tvp_int")]
public sealed partial record IntTvp(int Value);
Manual:
public sealed record OrderLineDto(int ProductId, int Qty) : ITvpMapper<OrderLineDto>
{
public static string TvpTypeName => "dbo.tvp_OrderLine";
public static IEnumerable<SqlDataRecord> MapAsSqlDataRecords(IEnumerable<OrderLineDto> items)
{
var meta = new[] { new SqlMetaData("ProductId", SqlDbType.Int), new SqlMetaData("Qty", SqlDbType.Int) };
foreach (var item in items)
{
var record = new SqlDataRecord(meta);
record.SetInt32(0, item.ProductId);
record.SetInt32(1, item.Qty);
yield return record;
}
}
}
Usage:
var sp = new StoredProcedureParametersBuilder("dbo", "sp_BulkInsert", capacity: 1)
.AddTvpParameter("OrderLines", orderLines)
.Build();
await dbContext.ExecuteNonQueryAsync(sp, ct);
Caching
var sp = new StoredProcedureParametersBuilder("dbo", "sp_GetProducts", capacity: 2)
.AddParameter("CategoryId", categoryId, SqlDbType.Int)
.AddFrozenCache("products:all") // immutable, process-lifetime
// .AddInMemoryCache("products:all", TimeSpan.FromMinutes(5))
// .AddRedisCache("products:all", TimeSpan.FromMinutes(5))
.Build();
Cache invalidation
Inject the ICaeriusNetCache façade to invalidate entries from any service:
public sealed class ProductsService(ICaeriusNetCache cache)
{
public async ValueTask InvalidateProductAsync(int id, CancellationToken ct)
{
await cache.RemoveAsync($"products:{id}", ct); // all tiers
await cache.RemoveAsync("products:all", CacheType.Frozen, ct);
// await cache.ClearAsync(CacheType.InMemory, ct); // dangerous; use sparingly
}
}
ClearAsync(CacheType.Redis) intentionally throws NotSupportedException — clearing a shared
distributed cache from a single service is almost never what you want.
To bound the in-memory tier, configure it explicitly at startup:
services.AddCaeriusNet(b => b
.WithSqlServerConnection(connectionString)
.WithInMemoryCacheOptions(new MemoryCacheOptions { SizeLimit = 50_000 }));
When SizeLimit is set, every cached entry is sized as 1 so the limit acts as a maximum entry
count.
Transactions
Stored-procedure transactions reuse a single SqlConnection for the whole scope and attach the
underlying SqlTransaction to every command. Caching is bypassed inside a transaction.
await using var tx = await dbContext.BeginTransactionAsync(IsolationLevel.ReadCommitted, ct);
var debit = new StoredProcedureParametersBuilder("dbo", "sp_DebitAccount", capacity: 2)
.AddParameter("AccountId", fromId, SqlDbType.Int)
.AddParameter("Amount", amount, SqlDbType.Decimal)
.Build();
var credit = new StoredProcedureParametersBuilder("dbo", "sp_CreditAccount", capacity: 2)
.AddParameter("AccountId", toId, SqlDbType.Int)
.AddParameter("Amount", amount, SqlDbType.Decimal)
.Build();
await tx.ExecuteNonQueryAsync(debit, ct);
await tx.ExecuteNonQueryAsync(credit, ct);
await tx.CommitAsync(ct); // omit -> auto-rollback on dispose
Design constraints (enforced at runtime):
| Rule | Behavior |
|---|---|
| State machine | Active → Committed / RolledBack / Poisoned |
| Single in-flight command | Concurrent commands throw InvalidOperationException |
| Cache bypass | No reads from cache, no writes to cache inside a transaction |
| Poison state | A failing command poisons the scope — only RollbackAsync/DisposeAsync remain valid |
| Auto-rollback | If CommitAsync is never called, the transaction rolls back on dispose |
| No nesting | BeginTransactionAsync on an active transaction throws NotSupportedException |
Write Operations
var sp = new StoredProcedureParametersBuilder("dbo", "sp_CreateProduct", capacity: 2)
.AddParameter("Name", name, SqlDbType.NVarChar)
.AddParameter("Price", price, SqlDbType.Decimal)
.Build();
await dbContext.ExecuteNonQueryAsync(sp, ct);
// Or retrieve a scalar return value
int newId = await dbContext.ExecuteScalarAsync<int>(sp, ct);
Multi-Result Sets
var sp = new StoredProcedureParametersBuilder("dbo", "sp_GetDashboard", capacity: 0).Build();
(IEnumerable<ProductDto> products, IEnumerable<CategoryDto> categories) =
await dbContext.QueryMultipleIEnumerableAsync<ProductDto, CategoryDto>(sp, ct);
Supported up to 5 result sets: QueryMultipleIEnumerableAsync<T1,T2> through
QueryMultipleIEnumerableAsync<T1,T2,T3,T4,T5>.
Available Query Methods
| Method | Returns |
|---|---|
FirstQueryAsync<T> |
T? (first row or null) |
QueryAsReadOnlyCollectionAsync<T> |
ReadOnlyCollection<T> |
QueryAsIEnumerableAsync<T> |
IEnumerable<T> |
QueryAsImmutableArrayAsync<T> |
ImmutableArray<T> |
ExecuteNonQueryAsync |
void |
ExecuteAsync |
void |
ExecuteScalarAsync<T> |
T |
Supported DTO Types
The source generator maps C# types to SQL Server types and generates the correct SqlDataReader calls.
| C# Type | SQL Server Type | Reader Method |
|---|---|---|
bool |
bit |
GetBoolean |
byte |
tinyint |
GetByte |
short |
smallint |
GetInt16 |
int |
int |
GetInt32 |
long |
bigint |
GetInt64 |
decimal |
decimal |
GetDecimal |
float |
real |
GetFloat |
Half |
real |
GetFloat (cast) |
double |
float |
GetDouble |
string |
nvarchar |
GetString |
char |
nchar |
GetString (cast) |
DateTime |
datetime2 |
GetDateTime |
DateOnly |
date |
DateOnly.FromDateTime |
TimeOnly |
time |
TimeOnly.FromTimeSpan |
DateTimeOffset |
datetimeoffset |
GetDateTimeOffset |
TimeSpan |
time |
GetTimeSpan |
Guid |
uniqueidentifier |
GetGuid |
byte[] |
varbinary |
GetFieldValue<byte[]> |
| Enums | (underlying type) | (underlying reader) |
Types without a native mapping fall back to sql_variant with a compile-time warning (CAERIUS005/006).
Observability
CaeriusNet uses [LoggerMessage] source-generated structured logging with zero-allocation event methods.
| Event Range | Category |
|---|---|
| 1xxx | In-Memory cache operations |
| 2xxx | Frozen cache operations |
| 3xxx | Redis cache operations |
| 4xxx | Database / stored procedure execution |
| 5xxx | Command execution lifecycle |
All events include structured properties (cache key, schema, procedure name, elapsed time, row count) for integration
with OpenTelemetry, Seq, Application Insights, or any ILogger sink.
Documentation
Full documentation, samples, and API reference: https://caerius.net
Source code & releases: https://github.com/CaeriusNET/CaeriusNet
License
MIT
| 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
- Aspire.Microsoft.Data.SqlClient (>= 13.2.2)
- Aspire.StackExchange.Redis.DistributedCaching (>= 13.2.2)
- Microsoft.Data.SqlClient (>= 7.0.0)
- Microsoft.Extensions.Caching.Memory (>= 10.0.6)
- Microsoft.Extensions.Caching.StackExchangeRedis (>= 10.0.6)
- Microsoft.Extensions.Configuration.Json (>= 10.0.6)
- Microsoft.Extensions.DependencyInjection (>= 10.0.6)
- Microsoft.Extensions.Logging.Abstractions (>= 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 | |
|---|---|---|---|
| 11.0.1 | 46 | 4/21/2026 | |
| 11.0.0 | 83 | 4/20/2026 | |
| 10.3.0 | 85 | 4/19/2026 | |
| 10.2.1 | 80 | 4/19/2026 | |
| 10.1.3 | 115 | 2/20/2026 | |
| 10.1.2 | 264 | 1/22/2026 | |
| 10.1.0 | 252 | 12/19/2025 | |
| 10.0.1 | 203 | 12/5/2025 | |
| 10.0.0.8-alpha | 169 | 11/2/2025 | |
| 10.0.0.7-alpha | 169 | 10/29/2025 | |
| 10.0.0.6-alpha | 163 | 10/29/2025 | |
| 10.0.0.5-alpha | 174 | 10/29/2025 | |
| 10.0.0.4-alpha | 169 | 10/28/2025 | |
| 10.0.0.3-alpha | 161 | 10/28/2025 | |
| 10.0.0.2-alpha | 166 | 10/27/2025 | |
| 10.0.0.1-alpha | 112 | 10/25/2025 | |
| 10.0.0 | 309 | 11/12/2025 | |
| 10.0.0-alpha | 245 | 10/21/2025 | |
| 9.4.1 | 233 | 9/5/2025 | |
| 9.4.0 | 316 | 9/3/2025 |
See https://github.com/CaeriusNET/CaeriusNet/releases for release notes.