AeroDB.Reactive 0.0.8.1-alpha

This is a prerelease version of AeroDB.Reactive.
dotnet add package AeroDB.Reactive --version 0.0.8.1-alpha
                    
NuGet\Install-Package AeroDB.Reactive -Version 0.0.8.1-alpha
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="AeroDB.Reactive" Version="0.0.8.1-alpha" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="AeroDB.Reactive" Version="0.0.8.1-alpha" />
                    
Directory.Packages.props
<PackageReference Include="AeroDB.Reactive" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add AeroDB.Reactive --version 0.0.8.1-alpha
                    
#r "nuget: AeroDB.Reactive, 0.0.8.1-alpha"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package AeroDB.Reactive@0.0.8.1-alpha
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=AeroDB.Reactive&version=0.0.8.1-alpha&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=AeroDB.Reactive&version=0.0.8.1-alpha&prerelease
                    
Install as a Cake Tool

AeroDB

AeroDB — SurrealDB Document Store for .NET

⚠️⚠️⚠️ ALPHA — This library is in active development. APIs may change without notice. Not recommended for production use. ⚠️⚠️⚠️

Compatible with SurrealDB 3.x and higher only. Not compatible with SurrealDB 2.x.

A .NET document store for SurrealDB with a Marten-compatible fluent API — idiomatic .NET sessions, schema management, indexing, and LINQ querying over SurrealDB's multi-model engine.

Goal

AeroDB brings a proven .NET document-store pattern — fluent sessions, LINQ querying, schema-first indexing — to SurrealDB's true multi-model engine. While MartenDB and Polecat layer document-store access on top of PostgreSQL and MSSQL (relational databases at their core), AeroDB unlocks SurrealDB's native document, graph, and time-series models in a single database. Graph traversals over relations, temporal aggregations, full-text and vector search, live queries, and geospatial operations all happen natively — no translation layers, no polyglot persistence. For AI workloads, SurrealDB's vector indexing (HNSW, DiskANN) and ml:: inference functions make AeroDB a natural fit for semantic search, RAG pipelines, and embedding-powered .NET applications.

If you've used Marten with PostgreSQL, AeroDB should feel like home — but the database underneath is built for a multi-model world.


Quick Start

// Configure
var store = Documents.For(opts =>
{
    opts.Namespace = "myapp";
    opts.Database   = "production";

    // Schema & indexes
    opts.Schema.For<User>()
        .Identity(u => u.Id)
        .Index(u => u.Email, c => c.IsUnique())
        .Index(u => new { u.FirstName, u.LastName })
        .FullTextIndex(u => u.Bio, "english");
});

await store.InitializeAsync();

// Write
await using var session = store.LightweightSession();
session.Store(new User { Name = "Alice", Email = "alice@example.com" });
await session.SaveChangesAsync();

// Read
await using var query = store.QuerySession();
var alice = await query.Query<User>()
    .FirstOrDefaultAsync(u => u.Email == "alice@example.com");

API Surface

Document Sessions

Method Purpose
store.LightweightSession() Read/write, no change tracking
store.QuerySession() Read-only
session.Store(entity) Insert or update
session.Delete(entity) Remove
session.Query<T>() LINQ query entry point
session.SaveChangesAsync() Commit unit of work

Schema & Indexing

opts.Schema.For<T>()
    .Identity(x => x.Id)                                    // designate primary key
    .Index(x => x.Prop)                                      // single-column btree
    .Index(x => x.Prop, c => { c.IsUnique(); c.WithName("…"); })  // with options
    .Index(x => new { x.FirstName, x.LastName })              // multi-column composite via anonymous type
    .UniqueIndex(x => x.Prop)                                 // shortcut unique
    .FullTextIndex(x => x.Body, "english")                    // full-text search
    .HnswIndex(x => x.Embedding, 1536)                        // vector (HNSW)
    .DiskannIndex(x => x.Embedding, 1536, vectorType: "F16")  // vector (DiskANN — SurrealDB 3.1+ server)
    .SpatialIndex(x => x.Location)                             // geo-spatial marker
    .MultiTenanted()                                           // tenant-id filtered
    .SetSchemaMode(SchemaMode.Strict)                          // SCHEMAFULL / Flexible
    .Schema("analytics_db");                                   // route to a SurrealDB database

Schema vs Database: AeroDB's .Schema("name") is named for Marten API parity, where it maps to a PostgreSQL schema. In SurrealDB, the hierarchy is Namespace → Database → Table (no RDBMS schemas). Under the hood, .Schema("name") switches to a different SurrealDB database within the same namespace via USE NS x DB name. This lets you logically partition tables (e.g., separate sales and analytics databases in a single store).

LINQ Querying

var results = await session.Query<User>()
    .Where(u => u.Age >= 18 && u.Name.Contains("A"))
    .OrderBy(u => u.Name)
    .Skip(20).Take(10)
    .ToListAsync();

Features

Event Sourcing & Change Logs

Full event sourcing with append, read, and projection support. Stream management via IAggregate and IEvent<T> with inline or async projections. A change-log feed captures ordered domain events for audit trails and CQRS pipelines.

var stream = await events.StartStream<Order>(orderId, new OrderPlaced { ... });
await session.SaveChangesAsync();

var aggregate = await events.AggregateStreamAsync<Order>(orderId);

Live Queries

Subscribe to real-time changes on any SurrealDB table. AeroDB wraps SurrealDB's LIVE SELECT capabilities into a push-based IObservable<T> interface — ideal for reactive UIs, dashboards, and cache invalidation.

var live = await session.LiveQuery<User>()
    .Where(u => u.Status == "active")
    .SubscribeAsync(change => Console.WriteLine($"Change: {change.Action} — {change.Data?.Id}"));

// Dispose to unsubscribe
await live.DisposeAsync();

Reactive Streams

Bridge live queries into Rx.NET IObservable<T> streams for declarative event processing. Filter by action type (created/updated/deleted), accumulate state over time, or compose with standard Rx operators — all without polling.

// Shortcut: filter by action directly on the builder
var created = session.LiveQuery<User>()
    .OnCreate()
    .Subscribe(user => Console.WriteLine($"New user: {user.Name}"));

var updated = session.LiveQuery<User>()
    .OnUpdate()
    .Subscribe(user => Console.WriteLine($"Updated: {user.Name}"));

var deleted = session.LiveQuery<User>()
    .OnDelete()
    .Subscribe(id => Console.WriteLine($"Deleted: {id}"));

// Or pipe through Rx.NET for custom composition
var creations = session.LiveQuery<User>()
    .ToObservable()
    .SelectOnCreate()
    .Subscribe(user => Console.WriteLine($"New user: {user.Name}"));

// Accumulate state from a live stream
var state = await session.LiveQuery<Order>()
    .ToObservable()
    .AggregateRecords(new Dictionary<string, Order>());

Graph Traversal

Native graph queries leveraging SurrealDB's relation support. Traverse edges, follow paths, and project graph results with a fluent builder — no manual SurrealQL required.

var friends = await session.Graph<User>()
    .Out<User>(edge => edge.FriendsWith)
    .Where(f => f.Age > 21)
    .ToListAsync();

Time-Series

Bucketed time-series aggregation with temporal grouping, windowing, and downsampling. Built on SurrealDB's native temporal functions for efficient analytics over time-bounded data.

var hourly = await session.TimeSeries<SensorReading>()
    .BucketBy(TimeSpan.FromHours(1))
    .Average(r => r.Temperature)
    .Between(start, end)
    .ToListAsync();

Spatial Queries

Geo-spatial filtering and ordering via SurrealDB's geometry type. Supports within-radius, bounding-box, and distance-order queries.

var nearby = await session.Query<Venue>()
    .Where(v => v.Location.IsWithinRadius(myPosition, 5000))
    .ToListAsync();

Compiled Queries

Pre-compiled, parameterized query plans for hot paths. Avoid re-translating LINQ expressions on every invocation — ideal for high-throughput endpoints and batch processing.

public class UsersByCity : CompiledQuery<User>
{
    public string City { get; set; }
    public override Expression<Func<IQueryable<User>, IQueryable<User>>> Query()
        => q => q.Where(u => u.City == City);
}

var nycUsers = await session.QueryAsync(new UsersByCity { City = "NYC" });

Raw Queries

Direct SurrealQL execution when LINQ isn't enough. Available on all session types for ad-hoc queries, administrative commands, or SurrealDB-specific features not yet abstracted.

var results = await session.RawQueryAsync<User>("SELECT * FROM user WHERE age > $min", new { min = 21 });
await session.ExecuteSqlAsync("DEFINE INDEX email_idx ON TABLE user COLUMNS email UNIQUE");

Multi-Tenancy

Built-in tenant isolation with automatic filter injection. Configure per-entity or globally, and all queries, inserts, and deletes are scoped to the active tenant ID.

Batching & Bulk Operations

Group multiple operations into a single SurrealQL transaction for reduced round-trips. Batch inserts, deletes, and mixed operations with atomic commit.

WolverineFx Integration

First-class integration with Wolverine for durable message queues, outbox patterns, saga persistence, and scheduled message delivery — all backed by SurrealDB.

Source Generators

Roslyn incremental generators for compile-time metadata (table names, record IDs, version fields) — no runtime reflection, no magic strings.

EF Core Bridge

Optional AeroDB.EntityFrameworkCore package coordinates transactions between AeroDB sessions and EF Core DbContext under a shared SurrealDB transaction. Use for hybrid workloads where part of your data flows through the document API and part through EF Core.

SurrealML Integration

Experimental AeroDB.ML package exposes SurrealDB's ml:: inference functions through a typed LINQ-like API — run model predictions directly inside your SurrealQL queries.


Credits

AeroDB was solely and greatly inspired by Jeremy D. Miller and the genius developers over at JasperFx and their brilliant library MartenDB for PostgreSQL, which we have used for years. AeroDB depends on SurrealDB.net, another awesome OSS library from the SurrealDB team.

Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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
0.0.8.1-alpha 38 7/5/2026
0.0.8-alpha 42 7/5/2026
0.0.7.2-alpha 43 7/5/2026
0.0.5-alpha 39 7/5/2026