/DB
Socigy.OpenSource.DB

Annotate once. Query forever.

Socigy.OpenSource.DB reads your annotated C# classes at build time and generates a fully typed PostgreSQL data layer: SELECT, INSERT, UPDATE, DELETE, joins, set operations, a unit-of-work context, and migrations, with zero boilerplate. Define your schema in C#, build, and every query method is already there. The generated code is plain source, so it runs under NativeAOT with no reflection.

version
v0.3.2
channel
stable
runtime
C#
license
MPL-2.0
Available on

Documentation

14 chapters
01
Getting started
Install the package, model your first table, and run a typed query through the generated context.
InstallationQuickstartProject structureConfiguration
02
Tutorial
Build a small HTTP API end to end: model a schema, migrate it, wire the typed context, and read and write through it.
What you'll buildModel the schemaGenerate and apply migrationsWire up the context
03
Core concepts
How the generator works, how connections and dependency injection are wired, and the transaction model.
How it worksConnections & DIThe database contextTransactions
04
Defining models
Map C# classes to PostgreSQL: columns, types, defaults, constraints, and special column kinds.
Tables & classesColumns & typesDefault valuesConstraints
05
Querying
Read and write rows with the generated, fully typed query API.
ReadingWriting
06
Dynamic tables
Bind one typed shape to many runtime-named tables for per-tenant, sharded, or time-partitioned data.
Declaring table typesRuntime operations
07
Recipes
Task-focused patterns for production applications, each built from the primitives in the other sections.
Keyset paginationSoft deletesAudit columnsMulti-tenant tables
08
Advanced
Value convertors, raw SQL procedures, portable DB constants, the type-safe CHECK DSL, and build-time diagnostics.
Value convertorsProcedure mappingDB constantsCheck constraint DSL
09
Observability
Emit executed SQL, parameters, and timings to OpenTelemetry and ILogger with zero per-call wiring.
Diagnostics & OpenTelemetryLogging
10
Performance
How the library performs against Dapper and EF Core, including NativeAOT, and how to reproduce the numbers.
Benchmarks
11
Migration
Generate DDL from annotated assemblies, apply schema changes, and hook in custom migration logic.
ConfigurationCLI toolSchema generationApplying migrations
12
Integrations
Wire the package into ASP.NET Core through generated DI extensions, or manage connections yourself.
ASP.NET CoreManual connectionsHashiCorp Vault
13
Testing
Unit-test your data-access code with no database by mocking the generated context interfaces.
Unit testing
14
Changelog
Release history: every fix, addition, and breaking change by version.
Changelog
Quickstart

From annotated class to typed queries, through the context.

Follow the steps to get DB wired up. Everything you need is in one package.

  1. 01Install the package. The generator, runtime, and migration CLI ship in one reference.
    dotnet add package Socigy.OpenSource.DB
  2. 02Model a table as a partial C# class. Attributes map it to PostgreSQL; the generator writes the rest.
    using Socigy.OpenSource.DB.Attributes;
    
    [Table("users")]
    public partial class User
    {
        [PrimaryKey, Default(DbDefaults.Guid.Random)]
        public Guid Id { get; set; }
    
        [Unique]
        public required string Username { get; set; }
    
        public string? Email { get; set; }
    
        [Default(DbDefaults.Time.Now)]
        public DateTime CreatedAt { get; set; }
    }
  3. 03Name the database in socigy.json. The generator emits a typed context (IAppDb) and its DI wiring.
    {
      "database": {
        "platform": "postgresql",
        "databaseName": "AppDb"
      }
    }
  4. 04Register the context, then read and write through it. No connection strings in your handlers, no SQL.
    builder.AddAppDb();                  // connection factory + migrations
    builder.Services.AddAppDbContext();  // ISocigyDatabaseFactory<IAppDb>
    
    var app = builder.Build();
    await app.EnsureLatestAppDbMigration();
    
    app.MapPost("/users", (User user, ISocigyDatabaseFactory<IAppDb> db) =>
        db.ExecuteAsync(d => d.Users.InsertAsync(user)));
    
    app.MapGet("/users/{name}", (string name, ISocigyDatabaseFactory<IAppDb> db) =>
        db.ExecuteAsync(d => d.Users.FirstOrDefaultAsync(u => u.Username == name)));
using Socigy.OpenSource.DB.Attributes;

[Table("users")]
public partial class User
{
    [PrimaryKey, Default(DbDefaults.Guid.Random)]
    public Guid Id { get; set; }

    [Unique]
    public required string Username { get; set; }

    public string? Email { get; set; }

    [Default(DbDefaults.Time.Now)]
    public DateTime CreatedAt { get; set; }
}