ZeroAlloc.ORM.Abstractions
2.4.0
dotnet add package ZeroAlloc.ORM.Abstractions --version 2.4.0
NuGet\Install-Package ZeroAlloc.ORM.Abstractions -Version 2.4.0
<PackageReference Include="ZeroAlloc.ORM.Abstractions" Version="2.4.0" />
<PackageVersion Include="ZeroAlloc.ORM.Abstractions" Version="2.4.0" />
<PackageReference Include="ZeroAlloc.ORM.Abstractions" />
paket add ZeroAlloc.ORM.Abstractions --version 2.4.0
#r "nuget: ZeroAlloc.ORM.Abstractions, 2.4.0"
#:package ZeroAlloc.ORM.Abstractions@2.4.0
#addin nuget:?package=ZeroAlloc.ORM.Abstractions&version=2.4.0
#tool nuget:?package=ZeroAlloc.ORM.Abstractions&version=2.4.0
ZeroAlloc.ORM
Source-generated raw-SQL data access for .NET: you write the SQL, the generator writes the ADO.NET, with no runtime reflection and NativeAOT-ready.
Why ZeroAlloc.ORM
- Close to hand-written ADO.NET. A 1,000-row read allocates 88,592 B, 0.4% more than hand-written ADO.NET's 88,200 B, where Dapper.AOT allocates 130,000 B in the same run.
- Ahead of Dapper.AOT on most SQLite workloads. A single-row read takes 1.10× the time of hand-written ADO.NET; Dapper.AOT takes 1.26× in the same run.
- Works under NativeAOT and trimming. CI publishes and runs AOT consumers on every PR, including ones that share the build with other source generators, where EF Core's precompiled queries collide.
- Compile-time diagnostics instead of runtime surprises. A non-partial method, a tuple that does not
match the SQL's statement count or a parameter with no binding is a build error,
ZAO001toZAO082.
Install
dotnet add package ZeroAlloc.ORM
dotnet add package ZeroAlloc.ORM.Generator
Then add your ADO.NET provider, such as Microsoft.Data.Sqlite, Npgsql or Microsoft.Data.SqlClient.
Quick start
using Microsoft.Data.Sqlite;
using System.Data.Async;
using System.Data.Async.Adapters;
using ZeroAlloc.ORM;
await using var db = new SqliteConnection("Data Source=:memory:").AsAsync();
await db.OpenAsync();
var customers = new CustomerRepository(db);
await customers.CreateTableAsync();
int id = await customers.AddAsync("Ada");
Console.WriteLine(await customers.FindAsync(id)); // Customer { Id = 1, Name = Ada }
public sealed record Customer(int Id, string Name);
public sealed partial class CustomerRepository(IAsyncDbConnection connection)
{
[Command("CREATE TABLE Customers (Id INTEGER PRIMARY KEY, Name TEXT NOT NULL)")]
public partial Task<int> CreateTableAsync(CancellationToken ct = default);
[Command("INSERT INTO Customers (Name) VALUES (@name) RETURNING Id", Kind = CommandKind.Identity)]
public partial Task<int> AddAsync(string name, CancellationToken ct = default);
[Query("SELECT Id, Name FROM Customers WHERE Id = @id")]
public partial Task<Customer?> FindAsync(int id, CancellationToken ct = default);
}
The generator fills in each partial method with typed parameter binding and row materialization
against AdoNet.Async's IAsyncDbConnection. There
is no LINQ provider, no expression compilation and no runtime reflection.
What you get
- Every common result shape: scalars, single rows, lists,
IAsyncEnumerable<T>streams and multi-result-set tuples such as(Order Head, IReadOnlyList<OrderLine> Lines). - Commands: rows affected, scalars, inserted identities and chunked multi-row bulk inserts.
- Stored procedures with output, input-output and return-value parameters.
- Rich types: enums as integers or names, value objects, multi-column composites such as
Money, and custom row factories. - Transactions by declaring an
IAsyncDbTransactionparameter. - Provider-aware checks for SQLite, PostgreSQL, SQL Server and MySQL.
- Migrations:
MigrationRunnerapplies embedded.sqlfiles, with locking for safe concurrent startup on PostgreSQL and SQL Server. - Observability through ZeroAlloc.Telemetry's
[Instrument]; see the observability recipe.
Every shape, option and diagnostic is in the reference.
Performance
SQLite, BenchmarkDotNet, captured at 2.3.1. Time is the same-run ratio against hand-written ADO.NET; allocations are exact bytes per call.
| Workload | ZA.ORM time | Dapper.AOT time | ZA.ORM alloc | Dapper.AOT alloc | Hand-written alloc |
|---|---|---|---|---|---|
| Single-row read | 1.10× | 1.26× | 1,568 B | 1,800 B | 1,232 B |
| 1,000-row read | 0.99× | 0.90× | 88,592 B | 130,000 B | 88,200 B |
| Head + 10 lines | 1.04× | 1.24× | 3,400 B | 4,072 B | 2,680 B |
Full tables, the insert workload, PostgreSQL and methodology: SQLite and PostgreSQL.
Learn more
- Documentation site: orm.zeroalloc.net
- Documentation source: the reference, cookbook, diagnostics and migrating to v2.
- Related packages: AdoNet.Async, ZeroAlloc.ValueObjects, ZeroAlloc.Telemetry and ZeroAlloc.Templates.
- Contributing: issues and pull requests are welcome on GitHub.
- CHANGELOG.
License
MIT. See LICENSE.
| 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
- No dependencies.
NuGet packages (1)
Showing the top 1 NuGet packages that depend on ZeroAlloc.ORM.Abstractions:
| Package | Downloads |
|---|---|
|
ZeroAlloc.ORM
Source-generator-based, NativeAOT-clean raw-SQL data access for .NET. Annotate partial methods with [Query]; the generator emits typed parameter binding + materialization against AdoNet.Async's IAsyncDbConnection. Zero runtime reflection. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.4.0 | 355 | 10/18/2026 |
| 2.3.4 | 661 | 10/16/2026 |
| 2.3.3 | 304 | 10/16/2026 |
| 2.3.2 | 1,421 | 10/15/2026 |
| 2.3.1 | 1,619 | 10/12/2026 |
| 2.3.0 | 602 | 10/11/2026 |
| 2.2.1 | 194 | 10/11/2026 |
| 2.2.0 | 4,018 | 9/30/2026 |
| 2.1.1 | 1,338 | 9/28/2026 |
| 2.1.0 | 847 | 9/27/2026 |
| 2.0.1 | 704 | 9/26/2026 |
| 2.0.0 | 722 | 9/25/2026 |
| 1.7.1 | 802 | 9/22/2026 |
| 1.7.0 | 711 | 9/22/2026 |
| 1.6.6 | 500 | 9/20/2026 |
| 1.6.5 | 101 | 9/20/2026 |
| 1.6.4 | 822 | 9/14/2026 |
| 1.6.3 | 1,218 | 8/7/2026 |
| 1.6.2 | 159 | 8/7/2026 |
| 1.6.0 | 1,440 | 6/4/2026 |