Core Reference
Kanject.Core.SqlDatabase
Beta · Aurora DSQL provider
The relational sibling to Kanject.Core.NoSqlDatabase. Same [Repository] shape, same source generator, same testable interface — running on Amazon Aurora DSQL. Currently in beta: the public API is stable, but a small number of provider-level options will still land in the next minor release.
Install
dotnet add package Kanject.Core.SqlDatabase Register
using Kanject.Core.SqlDatabase.Provider.AuroraDsql.Extensions;
builder.Services.AddAuroraDsqlSqlDatabase(options =>
{
options.ClusterEndpoint = appSettings.AuroraDsqlEndpoint;
options.AwsRegion = appSettings.AwsRegion;
options.Namespace = appSettings.DatabaseNamespace; // e.g. "prod"
}); Namespace prefixes every table at runtime (prod_Orders, staging_Orders) so multiple stages can share a single cluster safely.
Define a repository
using Kanject.Core.SqlDatabase.Abstractions;
using Kanject.Core.SqlDatabase.Abstractions.Attributes;
[Repository(table: "Orders")]
public partial interface IOrderRepository : IRepository<Order>
{
[Query(by: nameof(Order.CustomerId))]
Task<IReadOnlyList<Order>> ListByCustomerAsync(Guid customerId);
[Query(by: nameof(Order.Status), index: "ByStatus")]
Task<IReadOnlyList<Order>> ListByStatusAsync(OrderStatus status);
}
public record Order
{
[PrimaryKey] public Guid Id { get; init; }
[Indexed("ByCustomer")] public Guid CustomerId { get; init; }
[Indexed("ByStatus")] public OrderStatus Status { get; init; }
public decimal Total { get; init; }
public DateTimeOffset PlacedAt { get; init; }
} The partial interface is filled in by the source generator. [Query] methods compile to parameterised SQL; [Indexed] declares the secondary indexes they rely on. The shape is identical to Kanject.Core.NoSqlDatabase — teams already on NoSqlDatabase adopt SqlDatabase without learning a new pattern.
Use it
public class OrderService(IOrderRepository orders)
{
public Task<Order?> GetAsync(Guid id) => orders.FindAsync(id);
public Task<IReadOnlyList<Order>> ListForCustomerAsync(Guid customerId)
=> orders.ListByCustomerAsync(customerId);
public Task MarkPaidAsync(Guid id)
=> orders.UpdateAsync(id, o => o with { Status = OrderStatus.Paid });
} What ships with it
- Aurora DSQL provider — Amazon's serverless, multi-region-active SQL engine
- Source-generated repository implementations — zero reflection at runtime
- Strongly-typed indexed queries with compile-time validation
- Automatic
Namespaceprefixing for multi-stage isolation - Optimistic concurrency via
[Version]attribute - Mockable
IRepository<T>interface for unit tests
Beta caveats
Public APIs are stable. Provider-level options (IAM auth flow, custom retry strategies, read-replica routing) may grow in the next minor. Please report any roughness via /contact — beta feedback shapes the v1 cut.