NativeData
NativeData is an AOT-first ORM foundation for .NET 10, designed for applications that require Native AOT compilation and trimming compatibility.
Why NativeData?
Modern .NET applications increasingly target Native AOT and trimmed publish scenarios, where reflection-heavy ORMs fail at runtime. NativeData solves this by favoring:
- Compile-time metadata over runtime reflection
- Explicit provider wiring over dynamic provider loading
- Predictable SQL generation over broad dynamic conventions
Packages
| Package | Description |
|---|---|
NativeData.Abstractions | Core contracts and primitives (IRepository<T>, IEntityMap<T>, ISqlDialect) |
NativeData.Core | Runtime implementations (SqlRepository<T>, DbCommandExecutor, NativeDataContext) |
NativeData.Sqlite | SQLite provider (SqliteConnectionFactory, SqliteSqlDialect, UseSqlite) |
NativeData.Postgres | PostgreSQL provider (PostgresConnectionFactory, PostgresSqlDialect, UsePostgres) |
NativeData.Extensions.DependencyInjection | AddNativeData<TContext>() for Microsoft.Extensions.DependencyInjection |
NativeData.Generators | Source generator for [NativeDataEntity] annotated types |
NativeData.Analyzers | Roslyn analyzer for trim/AOT safety checks |
Quick Start
Install packages
dotnet add package NativeData.Core
dotnet add package NativeData.Sqlite
Define an entity
using NativeData.Abstractions;
[NativeDataEntity]
public class Product
{
public int Id { get; set; }
public string Name { get; set; } = "";
public decimal Price { get; set; }
}
Configure with DI (recommended)
using NativeData.Extensions.DependencyInjection;
using NativeData.Sqlite;
builder.Services.AddNativeData<AppContext>(o => o.UseSqlite("Data Source=myapp.db"));
// In a handler or service:
app.MapGet("/products/{id}", async (int id, AppContext db) =>
await db.Products.GetByIdAsync(id));
See DI Integration for full details on context definition, scoped lifecycle, and connection pooling.
Configure without DI
using NativeData.Core;
using NativeData.Sqlite;
var factory = new SqliteConnectionFactory("Data Source=myapp.db");
var executor = new DbCommandExecutor(factory);
var dialect = new SqliteSqlDialect();
var repo = new SqlRepository<Product>(executor, dialect, new ProductEntityMap());
await repo.InsertAsync(new Product { Id = 1, Name = "Widget", Price = 9.99m });
var product = await repo.GetByIdAsync(1);
Capabilities
- Repository-style API (
IRepository<T>) withGetByIdAsync,InsertAsync,UpdateAsync,DeleteByIdAsync - Fluent query builder (
NativeDataQuery<T>) with expression-basedWhere,OrderBy,Take,Skip- Source-generated predicate translation β no
Expression.Compile()at runtime - Supported operators:
==,!=,<,<=,>,>=,&&,||
- Source-generated predicate translation β no
- Provider-agnostic ADO.NET execution via
ICommandExecutor/ISqlDialect - SQLite and PostgreSQL provider packages
- DI integration via
AddNativeData<TContext>()with scoped context and singleton connection factory - Roslyn source generator for
[NativeDataEntity]β emitsIEntityMap<T>, filter/order helpers at compile time - Roslyn analyzer pack β 6 rules covering trim/AOT safety and entity mapping validation (ND0001βND0004, ND1001βND1002)
Out of Scope
- Migrations
- Change tracking / identity map
- Full LINQ translation (current subset is intentional for AOT safety)
Documentation
- Getting Started
- DI Integration
- Provider compatibility
- Project status and roadmap
- Release checklist
- Contributing guide
Build from Source
dotnet restore NativeData.slnx
dotnet build NativeData.slnx -warnaserror
dotnet test NativeData.slnx
License
NativeData is open source under the MIT License.