Jakar.Database
10.1.0-beta.1
dotnet add package Jakar.Database --version 10.1.0-beta.1
NuGet\Install-Package Jakar.Database -Version 10.1.0-beta.1
<PackageReference Include="Jakar.Database" Version="10.1.0-beta.1" />
<PackageVersion Include="Jakar.Database" Version="10.1.0-beta.1" />
<PackageReference Include="Jakar.Database" />
paket add Jakar.Database --version 10.1.0-beta.1
#r "nuget: Jakar.Database, 10.1.0-beta.1"
#:package Jakar.Database@10.1.0-beta.1
#addin nuget:?package=Jakar.Database&version=10.1.0-beta.1&prerelease
#tool nuget:?package=Jakar.Database&version=10.1.0-beta.1&prerelease
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>, andOwnedTableRecord<TSelf> - migration metadata and table creation helpers
- Dapper-friendly command parameter generation
- optional source-generated implementations of common
ITableRecord<TSelf>andTableRecord<TSelf>boilerplate - integration with
Jakar.SqlBuilder:ITableRecord<TSelf>implementsJakar.SqlBuilder.ISqlTable<TSelf>, so records work with the validated, dialect-aware fluent SQL builder's strongly-typednameof-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
DbDataReaderconstructor - 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
BearerPathPrefixessuch as/api: use JWT bearer - everything else: use the primary cookie scheme
Useful knobs in DbOptions:
AuthenticationSchemeBearerAuthenticationSchemeCookieAuthenticationSchemeBearerPathPrefixesForwardDefaultSelector
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 interfacesIRoleStore<RoleRecord>UserManager<UserRecord>,RoleManager<RoleRecord>, andSignInManager<UserRecord>- default token flows for password reset, email confirmation, and authenticator codes
The default IdentityOptions token names are aligned with the registered providers:
TokenOptions.DefaultProviderfor password resetTokenOptions.DefaultEmailProviderfor email confirmation and change-emailTokenOptions.DefaultPhoneProviderfor change-phone-numberTokenOptions.DefaultAuthenticatorProviderfor 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 | Versions 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. |
-
net10.0
- Dapper (>= 2.1.89)
- Dapper.Contrib (>= 2.0.78)
- dbup-postgresql (>= 7.0.1)
- dbup-sqlserver (>= 7.2.0)
- FirebirdSql.Data.FirebirdClient (>= 10.3.4)
- FluentMigrator.Abstractions (>= 8.0.1)
- Hardware.Info (>= 110.0.0.1)
- InterpolatedSql.Dapper (>= 2.5.1)
- Jakar.Extensions (>= 10.11.1)
- Jakar.Shapes (>= 10.2.0)
- Jakar.SqlBuilder (>= 10.2.0)
- MailKit (>= 4.18.2)
- Microsoft.AspNetCore.Authentication.Certificate (>= 10.0.13)
- Microsoft.AspNetCore.Authentication.Google (>= 10.0.13)
- Microsoft.AspNetCore.Authentication.JwtBearer (>= 10.0.13)
- Microsoft.AspNetCore.Authentication.MicrosoftAccount (>= 10.0.13)
- Microsoft.AspNetCore.Authentication.OpenIdConnect (>= 10.0.13)
- Microsoft.AspNetCore.Components.WebAssembly (>= 10.0.13)
- Microsoft.AspNetCore.OpenApi (>= 10.0.13)
- Microsoft.CodeAnalysis.CSharp (>= 5.9.0)
- Microsoft.Data.SqlClient (>= 7.1.1)
- Microsoft.Data.Sqlite (>= 10.0.13)
- Microsoft.Extensions.Caching.Hybrid (>= 10.11.0)
- Microsoft.Extensions.Caching.StackExchangeRedis (>= 10.0.13)
- Microsoft.Extensions.Diagnostics.HealthChecks (>= 10.0.13)
- Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions (>= 10.0.13)
- Microsoft.Extensions.Hosting (>= 10.0.13)
- Microsoft.Extensions.Hosting.Systemd (>= 10.0.13)
- Microsoft.Extensions.Hosting.WindowsServices (>= 10.0.13)
- Microsoft.Extensions.Http.Resilience (>= 10.11.0)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 10.0.13)
- Microsoft.Extensions.Options.DataAnnotations (>= 10.0.13)
- Microsoft.Extensions.ServiceDiscovery (>= 10.11.0)
- Microsoft.Identity.Client (>= 4.91.1)
- Microsoft.Identity.Web (>= 4.16.1)
- Microsoft.IdentityModel.JsonWebTokens (>= 8.23.0)
- Microsoft.IdentityModel.Protocols.OpenIdConnect (>= 8.23.0)
- Microsoft.IdentityModel.Tokens (>= 8.23.0)
- Microsoft.NETCore.Platforms (>= 8.0.0-preview.7.23375.6)
- MySqlConnector (>= 2.6.2)
- Npgsql (>= 10.0.3)
- Npgsql.OpenTelemetry (>= 10.0.3)
- OpenTelemetry (>= 1.20.1)
- OpenTelemetry.Api (>= 1.20.1)
- OpenTelemetry.Exporter.Console (>= 1.20.1)
- OpenTelemetry.Exporter.InMemory (>= 1.20.1)
- OpenTelemetry.Exporter.OpenTelemetryProtocol (>= 1.20.1)
- OpenTelemetry.Exporter.Prometheus.AspNetCore (>= 1.14.0-beta.1)
- OpenTelemetry.Exporter.Zipkin (>= 1.20.1)
- OpenTelemetry.Extensions.Hosting (>= 1.20.1)
- OpenTelemetry.Instrumentation.AspNetCore (>= 1.20.1)
- OpenTelemetry.Instrumentation.GrpcNetClient (>= 1.14.0-beta.1)
- OpenTelemetry.Instrumentation.Http (>= 1.20.1)
- OpenTelemetry.Instrumentation.Runtime (>= 1.20.1)
- Oracle.ManagedDataAccess.Core (>= 23.26.400)
- Otp.NET (>= 1.4.1)
- prometheus-net.AspNetCore (>= 8.2.1)
- prometheus-net.AspNetCore.HealthChecks (>= 8.2.1)
- prometheus-net.SystemMetrics (>= 3.1.0)
- Seq.Api (>= 2026.1.0)
- Seq.Apps (>= 2023.4.0)
- Seq.Extensions.Logging (>= 9.0.0)
- Serilog.Sinks.Seq (>= 9.1.0)
- Sigil (>= 5.0.0)
- SQLitePCLRaw.bundle_e_sqlite3 (>= 3.0.5)
- Swashbuckle.AspNetCore (>= 10.3.1)
- Swashbuckle.AspNetCore.Annotations (>= 10.3.1)
- System.IO.Hashing (>= 10.0.13)
- System.Security.Cryptography.Xml (>= 10.0.13)
- ZiggyCreatures.FusionCache.Backplane.Memory (>= 2.9.0)
- ZiggyCreatures.FusionCache.Backplane.StackExchangeRedis (>= 2.9.0)
- ZiggyCreatures.FusionCache.OpenTelemetry (>= 2.9.0)
- ZXing.Net (>= 0.16.11)
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 |
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.