Jakar.Database 10.1.0-beta.1

This is a prerelease version of Jakar.Database.
dotnet add package Jakar.Database --version 10.1.0-beta.1
                    
NuGet\Install-Package Jakar.Database -Version 10.1.0-beta.1
                    
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="Jakar.Database" Version="10.1.0-beta.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Jakar.Database" Version="10.1.0-beta.1" />
                    
Directory.Packages.props
<PackageReference Include="Jakar.Database" />
                    
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 Jakar.Database --version 10.1.0-beta.1
                    
#r "nuget: Jakar.Database, 10.1.0-beta.1"
                    
#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 Jakar.Database@10.1.0-beta.1
                    
#: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=Jakar.Database&version=10.1.0-beta.1&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Jakar.Database&version=10.1.0-beta.1&prerelease
                    
Install as a Cake Tool

Jakar.Database

Jakar.Database is a record-oriented ORM layer for .NET with:

  • IAsyncEnumerable<T>-first query surfaces
  • shared table metadata for common records
  • migration helpers with explicit rollback SQL
  • an incremental source generator that removes common ITableRecord<TSelf> boilerplate

Install

dotnet add package Jakar.Database

What It Provides

  • DbTable<TSelf> wrappers for common CRUD and streaming access
  • base records such as TableRecord<TSelf>, PairRecord<TSelf>, and OwnedTableRecord<TSelf>
  • migration metadata and table creation helpers
  • Dapper-friendly command parameter generation
  • optional source-generated implementations of common ITableRecord<TSelf> and TableRecord<TSelf> boilerplate
  • integration with Jakar.SqlBuilder: ITableRecord<TSelf> implements Jakar.SqlBuilder.ISqlTable<TSelf>, so records work with the validated, dialect-aware fluent SQL builder's strongly-typed nameof-based overloads

Source Generator Contract

The generator emits Create(DbDataReader) and the common abstract table-record members when your record:

  • is partial
  • implements ITableRecord<TSelf>
  • has a DbDataReader constructor
  • does not already declare those members manually

That lets you keep only the meaningful code in the record itself.

Example:

[Table(TABLE_NAME)]
[JsonModel]
public sealed partial record ExampleRecord : PairRecord<ExampleRecord>, ITableRecord<ExampleRecord>
{
    public const string TABLE_NAME = "examples";

    private static readonly SqlName __tableName = TABLE_NAME;
    public static ref readonly SqlName TableName => ref __tableName;

    public string Name { get; init; } = string.Empty;

    [JsonCreator]
    public ExampleRecord(RecordID<ExampleRecord> id, DateTimeOffset dateCreated) : base(in id, in dateCreated) { }

    internal ExampleRecord(DbDataReader reader) : base(reader)
    {
        Name = reader.GetFieldValue<ExampleRecord, string>(nameof(Name));
    }
}

In that shape, the generator supplies:

  • public static ExampleRecord Create(DbDataReader reader)
  • public override CommandParameters ToDynamicParameters()
  • public override ValueTask Export(NpgsqlBinaryExporter exporter, CancellationToken token)
  • public override ValueTask Import(NpgsqlBatchCommand batch, CancellationToken token)
  • protected override ValueTask Import(NpgsqlBinaryImporter importer, string propertyName, NpgsqlDbType postgresDbType, CancellationToken token)

Keep a manual implementation when a record needs special handling.

Records serialize with Jakar.Json only: ITableRecord<TSelf> requires IJsonSerializable<TSelf>, so each concrete record needs [JsonModel] (and [JsonCreator] on one constructor when it has several). AdditionalData is a JObjectNode? marked [JsonOverflow].

Authentication

The package now defaults to a hybrid ASP.NET Core authentication setup intended to work across:

  • WebAPI endpoints using bearer tokens
  • Blazor or other interactive browser hosts using cookies
  • non-browser clients that always send JWT bearer headers

DbOptions.AddAuthentication(...) registers:

  • a hybrid default scheme used by authorization
  • a named JWT bearer scheme
  • a primary cookie scheme
  • optional external provider cookies and remote auth handlers

Default selection rules:

  • Authorization: Bearer ... header: use JWT bearer
  • request path under BearerPathPrefixes such as /api: use JWT bearer
  • everything else: use the primary cookie scheme

Useful knobs in DbOptions:

  • AuthenticationScheme
  • BearerAuthenticationScheme
  • CookieAuthenticationScheme
  • BearerPathPrefixes
  • ForwardDefaultSelector

Fast host pattern:

DbOptions options = new()
                    {
                        TelemetrySource = ...,
                        ConnectionStringResolver = ...,
                        CommandTimeout = 30,
                        TokenIssuer = "MyApp",
                        TokenAudience = "MyApp",
                        LoggerOptions = new AppLoggerOptions(),
                        ConfigureCookieAuth = cookie =>
                                              {
                                                  cookie.Cookie.Name = "myapp.auth";
                                                  cookie.LoginPath = "/account/login";
                                                  cookie.AccessDeniedPath = "/account/access-denied";
                                              }
                    };

builder.Services.AddAuthorization();
options.AddAuthentication(builder);

var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();

Identity Services

DbServices.AddIdentityServices(...) wires Jakar.Database into ASP.NET Core Identity without Entity Framework.

The validated registration surface includes:

  • IUserStore<UserRecord> plus the login, claim, password, security-stamp, 2FA, email, lockout, authenticator-key, recovery-code, and phone-number store interfaces
  • IRoleStore<RoleRecord>
  • UserManager<UserRecord>, RoleManager<RoleRecord>, and SignInManager<UserRecord>
  • default token flows for password reset, email confirmation, and authenticator codes

The default IdentityOptions token names are aligned with the registered providers:

  • TokenOptions.DefaultProvider for password reset
  • TokenOptions.DefaultEmailProvider for email confirmation and change-email
  • TokenOptions.DefaultPhoneProvider for change-phone-number
  • TokenOptions.DefaultAuthenticatorProvider for authenticator codes

The generic overload also registers TTokenProvider under both nameof(TTokenProvider) and options.AppInformation.AppName, so custom token workflows can opt in explicitly without breaking the stock Identity methods.

Migration Guidance

Down migrations matter. Every migration that changes schema state should have an explicit rollback path.

Current rollback support covers:

  • shared function setup such as SetLastModified
  • enum migrations
  • table creation migrations
  • generated index migrations

MigrationManager.RevertMigrations(...) now executes registered DownSQL in reverse order and removes the corresponding applied migration rows.

Provider Notes

The long-term target is PostgreSQL plus Microsoft SQL Server. Today, the shared table metadata is moving in that direction, but parts of the query layer are still PostgreSQL-first. Treat SQL Server support as in progress unless a specific surface has been validated.

Build

dotnet build ..\Jakar.Database.slnx

Test

Fast generator-focused checks:

dotnet test ..\Jakar.Database.Tests\Jakar.Database.Tests.csproj --filter GeneratedRecordTests --no-restore

Authentication host checks:

dotnet test ..\Jakar.Database.Tests\Jakar.Database.Tests.csproj --filter AuthenticationConfigurationTests --no-restore

Identity registration checks:

dotnet test ..\Jakar.Database.Tests\Jakar.Database.Tests.csproj --filter IdentityServicesRegistrationTests --no-restore

Full integration tests require Docker because the existing suite uses PostgreSQL Testcontainers.

License

MIT. See LICENSE.txt.

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
10.1.0-beta.1 74 10/28/2026
10.0.0.1-beta 146 1/26/2026
9.0.0.8-beta 156 10/11/2025
9.0.0.6-beta 209 9/26/2025
9.0.0.5-beta 348 9/18/2025
9.0.0.4-beta 344 9/17/2025
9.0.0.2-beta 216 11/26/2024
9.0.0.1-beta 206 11/25/2024
7.0.0.33-beta 212 9/18/2024
7.0.0.32-beta 214 9/18/2024
7.0.0.31-beta 211 9/18/2024
7.0.0.30-beta 191 9/10/2024
7.0.0.29-beta 206 9/9/2024
7.0.0.28-beta 223 8/22/2024
7.0.0.27-beta 218 6/19/2024
7.0.0.26-beta 200 6/17/2024
7.0.0.25-beta 203 6/14/2024
7.0.0.24-beta 264 6/8/2024
7.0.0.23-beta 269 5/31/2024
6.8.2 644 8/29/2023
Loading failed

10.1.0: serializes with Jakar.Json only (built on Jakar.Extensions 10.11.0); Newtonsoft.Json, System.Text.Json and Npgsql.Json.NET are gone. Records are [JsonModel] types: ITableRecord<TSelf> requires IJsonSerializable<TSelf> (the generated ToJson/FromJson/TryFromJson replace TableRecord.FromJson/TryFromJson, and ToString() is the record as JSON). PairRecord.AdditionalData (and ResxRowRecord.AdditionalData) is a JObjectNode? marked [JsonOverflow]: unknown JSON members collect there and are written back. IPairRecord<TSelf> implements IJsonModel; WithAdditionalData takes JObjectNode?. JNode values bind to SQL parameters, batch commands and binary COPY as JSON text, and JNode-typed properties map to json columns. JsonSqlHandler and DbDataReader.GetData need IJsonSerializable<TValue>. JsonResult<TValue> writes the value's runtime [JsonModel] type (JsonCodecRegistry) and throws NotSupportedException for other types. JwtParser reads the payload with Jakar.Json: every claim is returned, and array roles become one claim each. EmailSettings is a [JsonModel]. CommandParameters and its renderers moved to Jakar.SqlBuilder (namespace Jakar.SqlBuilder); SqlParameter is now Jakar.SqlBuilder.CommandParameter. TableMetaData/ColumnMetaData implement ISqlCommandTable/ISqlCommandColumn; record ids implement ISqlParameterValue and bind as their Guid/long (AutoRecordID values were bound as the struct before). CommandParameters.Create<TSelf>(), AddGroup<TSelf>, Validate<TSelf>, ToPostgresParameter and ToSqlParameter are extension members in Jakar.Database. New: ToSqliteParameter, ToMySqlParameter and ToDbParameter(DbCommand) (any ADO.NET provider, typed with the new ColumnMetaData.AdoDbType), with DbColumnType.ToDbType/ToSqliteType/ToMySqlDbType; SqlCommand.ToCommand also dispatches SQLite and MySQL connections and falls back to any DbConnection. All conversions send null as DBNull.Value.