Curiosity

Connector Examples

Drop-in starters for the file formats and databases you're most likely to encounter when feeding a Curiosity workspace. Each page covers:

  • The NuGet package(s) you need on top of Curiosity.Library.
  • A minimal schema (one [Node] POCO, one [Key]).
  • A full Program.cs that streams the source, maps each record, and commits.
  • Notes on idempotency, large-file handling, and the source-specific gotchas.

These are templates — copy one, point it at your source, and adjust the schema. For the underlying API see Schemas, Ingestion, and Idempotency.

Index

JSON

Stream a JSON array of records with System.Text.Json.JsonSerializer.DeserializeAsyncEnumerable. Constant memory, no third-party dependencies.

CSV

Read row-by-row with CsvHelper. Header-mapped to your POCO, configurable delimiter and culture.

Parquet

Stream columnar rows with Parquet.Net. Reads one row-group at a time — works on multi-GB files.

Excel (.xlsx)

Iterate worksheet rows with ClosedXML or ExcelDataReader. Handles formulas and typed cells.

XML

Streaming XmlReader for large feeds; XDocument only for small files. No extra package required.

SQL Database

Cursor-paginated SELECT with Dapper over your provider (SQL Server, PostgreSQL, MySQL, SQLite, …).

Common scaffolding

Every example in this folder follows the same shape:

using Curiosity.Library;

[Node]
public class MyRecord
{
    [Key]       public string         Id   { get; set; }
    [Property]  public string         Name { get; set; }
    [Timestamp] public DateTimeOffset Time { get; set; }
}

using var graph = Graph.Connect(
    endpoint:      Environment.GetEnvironmentVariable("CURIOSITY_ENDPOINT")!,
    token:         Environment.GetEnvironmentVariable("CURIOSITY_TOKEN")!,
    connectorName: "my-connector");

await graph.CreateNodeSchemaAsync<MyRecord>();
graph.SetAutoCommitCost(everyNodes: 10_000);

// ... read records from source, graph.AddOrUpdate(...) ...

await graph.CommitPendingAsync();

The only thing that changes per format is the reader. The [Node] POCO and the commit loop stay the same. Read Schemas and Ingestion once and the rest is mechanical.

Picking the right reader

Source Reader Why
Small JSON (< 100 MB), simple shape JsonSerializer.Deserialize on the whole file Simplest, no async-stream complexity.
Large or unknown-size JSON DeserializeAsyncEnumerable or Utf8JsonReader Constant memory regardless of file size.
CSV with header row CsvHelper with ClassMap or attribute-based mapping Handles quoting, escaping, culture, type conversion.
Columnar bulk data Parquet.Net Reads compressed columns lazily — orders of magnitude faster on wide rows.
Excel as an integration surface ClosedXML for write-back; ExcelDataReader for read-only ingest ClosedXML is full-fidelity; ExcelDataReader is faster for huge sheets.
Existing relational system Dapper + the right ADO.NET provider Cursor-paginated reads keep memory bounded; provider handles drivers.
XML feed XmlReader.Create with a streaming loop Built-in to .NET, constant memory.
© 2026 Curiosity. All rights reserved.