Rystem.RepositoryFramework.Infrastructure.MsSql
10.0.7
dotnet add package Rystem.RepositoryFramework.Infrastructure.MsSql --version 10.0.7
NuGet\Install-Package Rystem.RepositoryFramework.Infrastructure.MsSql -Version 10.0.7
<PackageReference Include="Rystem.RepositoryFramework.Infrastructure.MsSql" Version="10.0.7" />
<PackageVersion Include="Rystem.RepositoryFramework.Infrastructure.MsSql" Version="10.0.7" />
<PackageReference Include="Rystem.RepositoryFramework.Infrastructure.MsSql" />
paket add Rystem.RepositoryFramework.Infrastructure.MsSql --version 10.0.7
#r "nuget: Rystem.RepositoryFramework.Infrastructure.MsSql, 10.0.7"
#:package Rystem.RepositoryFramework.Infrastructure.MsSql@10.0.7
#addin nuget:?package=Rystem.RepositoryFramework.Infrastructure.MsSql&version=10.0.7
#tool nuget:?package=Rystem.RepositoryFramework.Infrastructure.MsSql&version=10.0.7
Rystem.RepositoryFramework.Infrastructure.MsSql
Rystem.RepositoryFramework.Infrastructure.MsSql adds a lightweight SQL Server adapter for Repository Framework.
It reflects your model into one SQL table, but query translation is minimal: reads load rows from SQL and most Repository Framework filtering runs in memory.
Installation
dotnet add package Rystem.RepositoryFramework.Infrastructure.MsSql
Architecture
The package maps one table per model type.
- schema defaults to
dbo - table name defaults to
typeof(T).Name - every public property becomes a column
- one property must be marked as the primary key
- non-primitive properties are stored as JSON strings in SQL
This makes the provider easy to configure, but it is not a full LINQ-to-SQL translation layer.
Registration APIs
Available on all three patterns:
WithMsSql(...)
Supported for:
IRepositoryBuilder<T, TKey>ICommandBuilder<T, TKey>IQueryBuilder<T, TKey>
Example
This mirrors the API tests.
builder.Services.AddRepository<Cat, Guid>(repositoryBuilder =>
{
repositoryBuilder.WithMsSql(msSqlBuilder =>
{
msSqlBuilder.Schema = "repo";
msSqlBuilder.ConnectionString = builder.Configuration["ConnectionStrings:Database"];
msSqlBuilder
.WithPrimaryKey(x => x.Id, column =>
{
column.ColumnName = "Key";
})
.WithColumn(x => x.Paws, column =>
{
column.ColumnName = "Zampe";
column.IsNullable = true;
});
});
});
Example model from the tests:
public sealed class Cat
{
public Guid Id { get; set; }
public string? Name { get; set; }
public int? Something { get; set; }
public IEnumerable<Room> Rooms { get; set; } = new List<Room>();
public int Paws { get; set; }
}
Rooms is a non-primitive property, so it is stored as JSON in SQL.
Builder API
IMsSqlRepositoryBuilder<T, TKey> exposes:
| Member | Purpose |
|---|---|
ConnectionString |
SQL Server connection string |
Schema |
Target schema, default dbo |
TableName |
Target table name, default typeof(T).Name |
WithPrimaryKey(expr, cfg) |
Mark one property as the SQL primary key |
WithColumn(expr, cfg) |
Customize another column |
PropertyHelper<T> exposes:
| Property | Notes |
|---|---|
ColumnName |
Override the SQL column name |
IsNullable |
Controls NOT NULL generation |
SqlType |
Override the inferred SQL type |
Dimension |
Override SQL type dimensions such as (100) or (14,4) |
IsAutomaticCreated |
Present in the API, but not currently used by the repository implementation |
Type mapping
The package infers SQL types from CLR property types.
Examples from the current mapper:
Guid→uniqueidentifierstring→varchar(100)DateTime→datetime2decimal→decimal(14,4)- non-primitive types →
varchar(max)with JSON payloads
Nullable CLR types become nullable columns unless you override them.
Required configuration
In practice you need:
ConnectionString- one
WithPrimaryKey(...)call
If no primary key is configured, BootstrapAsync() throws.
Warm-up and provisioning
This package has startup hooks, but the current implementation is not as complete as the old README implied.
What BootstrapAsync() actually does
SqlRepository<T, TKey>.BootstrapAsync():
- checks whether a primary key is configured
- checks whether any columns exist for the table name
- creates the schema if missing
- creates the table if missing
Important current limitation
Despite method names and earlier docs, the package does not currently merge new columns into an existing table.
The helper named MsSqlCreateTableOrMergeNewColumnsInExistingTableAsync() is empty.
Registration-shape caveat
- repository and command registrations add warm-up hooks that call that empty helper
- query registrations add a warm-up hook that calls
BootstrapAsync()
So auto-provisioning is currently more reliable for query registrations than for repository/command registrations.
If you depend on startup schema creation for repository or command registrations, verify it in your environment instead of assuming it happens.
Query behavior
QueryAsync(...) runs this shape of SQL:
select [col1],[col2],... from [Schema].[TableName]
It does not translate Repository Framework filters to SQL WHERE, ORDER BY, TOP, or paging clauses.
Instead it:
- reads rows from SQL
- materializes models
- applies Repository Framework filters in memory
Practical consequence:
Where, ordering, paging, and aggregates are mostly client-side- large tables will be scanned more than you might expect
Aggregate behavior
Aggregate operations such as:
CountSumMinMaxAverage
materialize items through the repository query flow and then compute results in memory.
CRUD behavior
GetAsyncandExistAsyncquery by the configured primary key column- primitive keys are stored with
ToString() - non-primitive keys are stored as JSON in the primary key column
- inserts and updates only send non-null property values as SQL parameters
Important consequence:
- the package cannot update a column to
NULLthrough the current parameter-building logic
Batch behavior
BatchAsync(...) is a sequential loop over insert, update, and delete calls.
There is:
- no SQL transaction wrapping the whole batch
- no bulk insert path
- no rollback behavior
Other limitations to know about
- only one primary key column is supported
- there is no composite key mapping
- table existence checks use
INFORMATION_SCHEMA.COLUMNSfiltered only by table name, not by schema name - method names suggest schema evolution support, but the implementation is currently create-only
CQRS examples
builder.Services.AddCommand<Cat, Guid>(commandBuilder =>
{
commandBuilder.WithMsSql(msSqlBuilder =>
{
msSqlBuilder.ConnectionString = builder.Configuration["ConnectionStrings:Database"];
msSqlBuilder.WithPrimaryKey(x => x.Id, column =>
{
column.ColumnName = "Key";
});
});
});
builder.Services.AddQuery<Cat, Guid>(queryBuilder =>
{
queryBuilder.WithMsSql(msSqlBuilder =>
{
msSqlBuilder.ConnectionString = builder.Configuration["ConnectionStrings:Database"];
msSqlBuilder.WithPrimaryKey(x => x.Id, column =>
{
column.ColumnName = "Key";
});
});
});
When to use this package
Use it when you want:
- a simple reflection-based SQL Server backend
- explicit table and column naming control
- JSON storage for complex properties without extra mapping layers
Be careful if you expect server-side query translation or automatic schema evolution, because the current implementation is much thinner than that.
| 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
- Microsoft.Data.SqlClient (>= 7.0.0)
- Rystem.RepositoryFramework.Abstractions (>= 10.0.7)
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.0.7 | 50 | 3/26/2026 |
| 10.0.6 | 154,649 | 3/3/2026 |
| 10.0.5 | 91 | 2/22/2026 |
| 10.0.4 | 98 | 2/9/2026 |
| 10.0.3 | 147,913 | 1/28/2026 |
| 10.0.1 | 209,082 | 11/12/2025 |
| 9.1.3 | 236 | 9/2/2025 |
| 9.1.2 | 764,415 | 5/29/2025 |
| 9.1.1 | 97,805 | 5/2/2025 |
| 9.0.32 | 186,698 | 4/15/2025 |
| 9.0.31 | 5,781 | 4/2/2025 |
| 9.0.30 | 88,799 | 3/26/2025 |
| 9.0.29 | 9,013 | 3/18/2025 |
| 9.0.28 | 261 | 3/17/2025 |
| 9.0.27 | 241 | 3/16/2025 |
| 9.0.26 | 244 | 3/13/2025 |
| 9.0.25 | 52,110 | 3/9/2025 |
| 9.0.21 | 311 | 3/6/2025 |
| 9.0.20 | 19,558 | 3/6/2025 |
| 9.0.19 | 301 | 3/6/2025 |