A .NET binding for Kuzu graph database APIs with strict feature and performance parity goals.
| Package | NuGet |
|---|---|
| Ladybug | |
| Ladybug.Native | |
| Ladybug.Extensions |
dotnet add package Ladybug
dotnet add package Ladybug.ExtensionsLadybug.Native is pulled in automatically as a dependency of Ladybug.
using Ladybug;
using Ladybug.Extensions;
await using var client = new LadybugClient(nativeLibrary);
var result = await client.ExecuteAsync(
"MATCH (p:Person) RETURN p.name, p.age");
// LINQ mapping with typed row accessor
var people = result.Select(r => new
{
Name = r.Get<string>("p.name"),
Age = r.Get<int>("p.age")
});
foreach (var p in people)
Console.WriteLine($"{p.Name} is {p.Age} years old");For a full runnable example with fraud detection, recommendations, JSON/CSV export, true-streaming fallback behavior, DI, health checks, and resilience, see the Example project.
| Package | Description |
|---|---|
| Ladybug | Managed API surface, LadybugClient, ILadybugExecutor, and differential smoke runner. |
| Ladybug.Native | Native abstraction layer modelling the Kuzu C API contract (INativeLibrary). |
| Ladybug.Extensions | LINQ mapping, JSON/CSV export, DataTable, streaming, DI, Options, health checks, and resilience policies. |
// Project rows into dictionaries
IEnumerable<IReadOnlyDictionary<string, object?>> dicts = result.ToDictionaries();
// Map rows with a typed IRowAccessor
IEnumerable<T> items = result.Select(r => new MyDto(r.Get<string>("name"), r.Get<int>("age")));
// Materialize into a list
List<T> list = result.ToList(r => new MyDto(r.Get<string>("name"), r.Get<int>("age")));
// Extract a single scalar value
string name = result.Scalar<string>("name");
int value = result.Scalar<int>(0);Typed access to row values by column name (case-insensitive) or index:
T value = accessor.Get<T>("columnName");
T value = accessor.Get<T>(0);
T? valueOrNull = accessor.GetOrDefault<T>("columnName");
T? valueOrFallback = accessor.GetOrDefault<T>(0, fallback);// Full result with metadata (columns, rows, sourceLibrary, durationMs)
string json = result.ToJson();
// Array of row objects keyed by column names
string jsonArray = result.ToJsonArray();DataTable dt = result.ToDataTable();string csv = result.ToCsv(); // comma-separated
string tsv = result.ToCsv(separator: "\t"); // tab-separated// Stream rows one by one as IRowAccessor
await foreach (var row in executor.StreamAsync("MATCH (n) RETURN n.id"))
{
Console.WriteLine(row.Get<string>(0));
}
// Stream with a mapper
await foreach (var id in executor.StreamAsync("MATCH (n) RETURN n.id", r => r.Get<string>(0)))
{
Console.WriteLine(id);
}When the underlying native adapter implements INativeStreamingLibrary, Ladybug uses row-by-row streaming without full result materialization. Otherwise it falls back to buffered execution.
// Basic registration
services.AddLadybugClient<MyNativeLibrary>();
// With options
services.AddLadybugClient<MyNativeLibrary>(opts =>
{
opts.DatabasePath = "./mydb";
opts.ReadOnly = true;
opts.MaxThreads = 4;
opts.BufferPoolSize = 256 * 1024 * 1024;
});
// Health check
services.AddHealthChecks().AddLadybugCheck();
// Optional resilience wrapper for enterprise workloads
services.AddResilientLadybugExecutor(opts =>
{
opts.Timeout = TimeSpan.FromSeconds(5);
opts.MaxRetryAttempts = 1;
opts.RetryDelay = TimeSpan.FromMilliseconds(50);
opts.CircuitBreakerFailureThreshold = 3;
opts.CircuitBreakerBreakDuration = TimeSpan.FromSeconds(5);
});Registers INativeLibrary, LadybugClient, and ILadybugExecutor as singletons.
LadybugClient emits OpenTelemetry-compatible diagnostics:
- Activity source:
Ladybug - Meter:
Ladybug - Counter:
ladybug.query.count - Counter:
ladybug.query.errors - Counter:
ladybug.query.cancellations - Histogram:
ladybug.query.duration.ms
These signals can be exported through standard OpenTelemetry pipelines for dashboards and alerts.
- .NET 10 (net10.0)
- .NET 8 (net8.0)
dotnet restore
dotnet build ladybug-csharp.sln -c Releasedotnet test ladybug-csharp.sln -c Releasedotnet run -c Release --project benchmarks/Ladybug.Benchmarks/Ladybug.Benchmarks.csprojDeterministic CI gate mode:
LADYBUG_BENCH_RATIO_MAX=1.10 dotnet run -c Release --project benchmarks/Ladybug.Benchmarks/Ladybug.Benchmarks.csproj -- --ci-gateSee:
docs/differential-smoke-spec.mddocs/parity-matrix.md
MIT. See LICENSE.