CosmoSQLClient.MsSql.EntityFrameworkCore
7.31.0
dotnet add package CosmoSQLClient.MsSql.EntityFrameworkCore --version 7.31.0
NuGet\Install-Package CosmoSQLClient.MsSql.EntityFrameworkCore -Version 7.31.0
<PackageReference Include="CosmoSQLClient.MsSql.EntityFrameworkCore" Version="7.31.0" />
<PackageVersion Include="CosmoSQLClient.MsSql.EntityFrameworkCore" Version="7.31.0" />
<PackageReference Include="CosmoSQLClient.MsSql.EntityFrameworkCore" />
paket add CosmoSQLClient.MsSql.EntityFrameworkCore --version 7.31.0
#r "nuget: CosmoSQLClient.MsSql.EntityFrameworkCore, 7.31.0"
#:package CosmoSQLClient.MsSql.EntityFrameworkCore@7.31.0
#addin nuget:?package=CosmoSQLClient.MsSql.EntityFrameworkCore&version=7.31.0
#tool nuget:?package=CosmoSQLClient.MsSql.EntityFrameworkCore&version=7.31.0
CosmoSQLClient
A lightweight, high-performance database client library for .NET designed for low-latency, high-throughput applications. CosmoSQLClient provides a unified interface for multiple database engines while minimizing memory allocations and binary footprint.
NuGet Packages
| Package | NuGet |
|---|---|
CosmoSQLClient.Core |
|
CosmoSQLClient.MsSql |
|
CosmoSQLClient.Postgres |
|
CosmoSQLClient.MySql |
|
CosmoSQLClient.Oracle |
|
CosmoNova.Engine.Sqlite (pure-managed SQLite engine; lives in CosmoStack; renamed from CosmoSQLClient.Sqlite) |
|
CosmoSQLClient.CosmoKv |
|
CosmoSQLClient.CosmoKvHttp |
|
CosmoSQLClient.CosmoKv.Cli (dotnet tool: cosmokv) |
|
CosmoSQLClient.MsSql.EntityFrameworkCore |
|
CosmoSQLClient.Postgres.EntityFrameworkCore |
|
CosmoSQLClient.MySql.EntityFrameworkCore |
|
CosmoSQLClient.Sqlite.EntityFrameworkCore (legacy — wrapped the pre-6.x native-backed driver; no longer maintained) |
Key Features
- High-Performance Pipeline Architecture: Built on top of
System.IO.Pipelinesfor efficient asynchronous I/O and protocol decoding. - Zero-Allocation Row Decoding: Employs a strictly-constrained generic pipeline and
struct-based token handlers to eliminate boxing and reduce heap pressure. - Native Streaming: Supports
IAsyncEnumerablefor row-by-row processing, ideal for large datasets and reactive streams. - Lightweight Footprint: Core library and providers are significantly smaller than standard ADO.NET implementations (e.g., MSSQL provider is ~207KB vs ~17MB for Microsoft.Data.SqlClient).
- Unified API: Shared
ISqlDatabaseinterface across all supported engines (MSSQL, PostgreSQL, MySQL, Oracle, SQLite, CosmoKv, CosmoKvHttp). - Entity Framework Core Integration: Optional bridge packages let you use CosmoSQLClient connections with the standard EF Core relational providers for MSSQL, PostgreSQL, MySQL, and SQLite.
- Advanced JSON Support: Direct streaming of database results to JSON (NDJSON/JSON array) with minimal buffering.
Supported Database Engines
| Engine | Protocol | Supported Features |
|---|---|---|
| MSSQL | TDS 7.x | Integrated Security (NTLMv2), Stored Procedures, Transactions, Named Instances |
| PostgreSQL | Frontend/Backend 3.0 | MD5/Scram-SHA-256 Auth, Transactions, Parameterized Queries |
| MySQL | MySQL Protocol 4.1+ | Standard Auth, Transactions, Parameterized Queries |
| Oracle | Oracle Net (TNS) + TTC | O5LOGON 12c Auth (PBKDF2-SHA512 + AES-256), Transactions, :name Binds, Connection Pooling |
| SQLite | Local File | Native engine integration, Online Backup, Transactions |
| CosmoKv (embedded) | In-process facade over the CosmoNova engine (T-SQL parser + executor + LSM storage in one assembly) | Full T-SQL subset, MVCC transactions, online COSMOBAK backup |
| CosmoKvHttp | HTTP/JSON wire to a CosmoKvD daemon | Same T-SQL surface as CosmoKv, exposed over the network for multi-process sharing |
| CosmoKvPipes | Unix-pipes wire to a CosmoKvD daemon | Same T-SQL surface as CosmoKvHttp; faster than HTTP for co-located processes |
CosmoKv driver (v6.0+) — facade over CosmoNova
Starting at v6.0, CosmoSQLClient.CosmoKv is a thin ISqlDatabase facade (~250 LOC). The T-SQL engine that used to live in this package was extracted into the standalone CosmoNova package (storage + engine in one assembly); this driver depends on it and exposes the connection API via CosmoKvConnection / CosmoKvConfiguration.
using CosmoSQLClient.CosmoKv;
await using var conn = await CosmoKvConnection.OpenAsync(
new CosmoKvConfiguration { DataSource = "/var/lib/myapp" });
await conn.ExecuteAsync("CREATE TABLE users (id BIGINT IDENTITY PRIMARY KEY, name VARCHAR(64));");
await conn.ExecuteAsync(
"INSERT INTO users (name) VALUES (@n);",
new List<SqlParameter> { SqlParameter.Named("@n", SqlValue.From("Ada")) });
var rows = await conn.QueryAsync("SELECT * FROM users;");
The supported T-SQL surface (as of CosmoNova 1.0+) is documented in the CosmoNova README. Highlights: full DDL (CREATE TABLE/INDEX with IF NOT EXISTS), JOIN (INNER/LEFT/RIGHT/FULL/CROSS), GROUP BY + GROUPING SETS, PIVOT/UNPIVOT, CTEs, windowed functions, IDENTITY, UNIQUE/PRIMARY KEY constraints, OUTPUT clauses, MERGE, scalar UDFs, stored procedures, triggers (subset), OPTION (RECOMPILE|FORCE ORDER|MAXDOP n) hints, hash join + cost-based join reordering. Embedded benchmarks show 32–60× faster than SQL Server 2025 on the same T-SQL.
Exceptions thrown by the engine (SqlTransactionConflictException, UniqueConstraintViolationException) live in the CosmoNova.Sql namespace as of v6.0. If your code catches them, add using CosmoNova.Sql; where needed.
Oracle driver — native TNS/TTC, no Oracle Client
CosmoSQLClient.Oracle speaks Oracle Net (TNS) transport and the TTC protocol directly, in the same wire dialect as the python-oracledb thin driver. There is no Oracle Instant Client, no OCI, and no native dependency — it is pure managed .NET, multi-targeting net10.0 and netstandard2.0.
The same code path talks to real Oracle Database and to the CosmoNova Oracle engine exposed by a CosmoKvD daemon, so you can develop against the lightweight engine and deploy against Oracle without changing a line.
using CosmoSQLClient.Core;
using CosmoSQLClient.Oracle;
await using var conn = await OracleConnection.OpenAsync(
"Data Source=dbhost:1521/FREEPDB1;User Id=system;Password=your_password");
// Named binds use Oracle's ':name' form.
var rows = await conn.QueryAsync(
"SELECT employee_id, last_name, salary FROM employees WHERE department_id = :dept",
new[] { new SqlParameter(SqlValue.From(90)) });
foreach (var row in rows)
Console.WriteLine($"{row["LAST_NAME"].AsString()}: {row["SALARY"].AsDecimal()}");
Connection strings
Easy Connect (host:port/service) is the recommended form; the discrete keys are also accepted.
Data Source=dbhost:1521/FREEPDB1;User Id=system;Password=secret
Host=dbhost;Port=1521;Service Name=FREEPDB1;User Id=scott;Password=tiger;Connection Timeout=15
| Key | Aliases | Notes |
|---|---|---|
Data Source |
DataSource, Server, Host |
Easy Connect host[:port][/service]; port defaults to 1521 |
Service Name |
ServiceName, SID, Database, Initial Catalog |
Required if not given in Data Source |
User Id |
User ID, UID, User, Username |
|
Password |
PWD |
|
Connection Timeout |
Connect Timeout, Timeout |
Seconds; default 15 |
ADO.NET surface
The provider implements the standard ADO.NET types, so it drops into existing DbConnection-based code and works with micro-ORMs such as Dapper:
await using DbConnection conn = new OracleConnection(connStr);
await conn.OpenAsync();
await using DbCommand cmd = conn.CreateCommand();
cmd.CommandText = "SELECT COUNT(*) FROM orders WHERE order_date > :since";
cmd.Parameters.AddWithValue(":since", new DateTime(2026, 1, 1));
var count = Convert.ToInt64(await cmd.ExecuteScalarAsync());
OracleConnection · OracleCommand · OracleDataReader · OracleParameter · OracleTransaction · OracleConnectionPool, plus the shared ISqlDatabase interface.
Server errors surface as OracleServerException, which derives from DbException (like SqlException and NpgsqlException), so provider-agnostic handlers catch it. Code carries the numeric ORA code:
try { await conn.ExecuteAsync("DROP TABLE staging"); }
catch (OracleServerException ex) when (ex.Code == 942) { /* ORA-00942: table does not exist */ }
Transactions
Oracle begins a transaction implicitly at the first DML. BeginTransactionAsync() turns off the per-statement autocommit; CommitAsync() / RollbackAsync() end it.
await conn.BeginTransactionAsync();
await conn.ExecuteAsync("UPDATE accounts SET balance = balance - :amt WHERE id = :id",
new[] { new SqlParameter(SqlValue.From(100m)), new SqlParameter(SqlValue.From(1)) });
await conn.CommitAsync(); // or RollbackAsync()
Connection pooling
await using var pool = new OracleConnectionPool(connStr, maxConnections: 10);
var rows = await pool.QueryAsync("SELECT * FROM products WHERE list_price > :p",
new[] { new SqlParameter(SqlValue.From(500m)) });
Pooled operations acquire, run, and release per call; because each call may borrow a different physical connection, transactions are not supported on the pool — use a dedicated OracleConnection for transactional work.
Type mapping
| Oracle type | .NET type via SqlValue |
|---|---|
NUMBER |
long when integral and in range, else decimal |
VARCHAR2, CHAR, LONG |
string (AL32UTF8) |
NVARCHAR2, NCHAR |
string (AL16UTF16 / UTF-16BE) |
DATE, TIMESTAMP, TIMESTAMP WITH LOCAL TIME ZONE |
DateTime |
TIMESTAMP WITH TIME ZONE |
DateTimeOffset |
BINARY_FLOAT / BINARY_DOUBLE |
float / double |
RAW |
byte[] |
BOOLEAN (23ai) |
bool |
Verification
The driver is checked against a 1083-probe corpus run head-to-head between real Oracle Database and the CosmoNova Oracle engine (tools/OracleParity/DriverParity in CosmoStack), currently at 1083/1083 (100%), plus an integration suite that must pass identically against both.
Not yet supported
LOB streaming (CLOB/BLOB read as text), REF CURSOR, PL/SQL OUT binds, array binds, TLS/native network encryption, wallet or external authentication, and an EF Core bridge package. Contributions welcome — the wire layer lives in src/CosmoSQLClient.Oracle/Proto.
Gotcha: QueryAsync<T> resolves to this library, not Dapper
This applies to every CosmoSQLClient provider, not just Oracle. ISqlDatabase declares an instance method QueryAsync<T>(string, ...), and in C# an instance method always wins over an extension method. So with using Dapper; in scope:
await using var conn = new OracleConnection(cs);
// ⚠ Binds to CosmoSQLClient's ISqlDatabase.QueryAsync<T> — NOT Dapper.
// For a POCO this maps by column name; for a primitive such as int it
// returns default(T) per row (silently 0), because that mapper expects
// a class with settable properties.
var bad = await conn.QueryAsync<int>("SELECT 9 FROM DUAL"); // → 0
// ✅ Reach Dapper explicitly, either way:
var good1 = await SqlMapper.QueryAsync<int>(conn, "SELECT 9 FROM DUAL"); // → 9
IDbConnection db = conn;
var good2 = await db.QueryAsync<int>("SELECT 9 FROM DUAL"); // → 9
Dapper's other entry points have no instance-method counterpart and therefore bind to Dapper as expected — Query<T>, QueryFirstAsync<T>, QuerySingleAsync<T>, ExecuteAsync, POCO mapping and :name binds are all verified working against real Oracle.
Installation
Add the package for your specific database engine:
dotnet add package CosmoSQLClient.MsSql
dotnet add package CosmoSQLClient.Postgres
dotnet add package CosmoSQLClient.MySql
dotnet add package CosmoSQLClient.Oracle # native TNS/TTC — no Oracle Instant Client
dotnet add package CosmoNova.Engine.Sqlite # pure-managed SQLite engine (renamed from CosmoSQLClient.Sqlite)
dotnet add package CosmoSQLClient.CosmoKv # embedded T-SQL on CosmoKv
dotnet add package CosmoSQLClient.CosmoKvHttp # T-SQL over HTTP to CosmoKvD
For Entity Framework Core integration, install the matching bridge package for your provider:
dotnet add package CosmoSQLClient.MsSql.EntityFrameworkCore
dotnet add package CosmoSQLClient.Postgres.EntityFrameworkCore
dotnet add package CosmoSQLClient.MySql.EntityFrameworkCore
| Provider package | EF Core bridge package | Extension method |
|---|---|---|
CosmoSQLClient.MsSql |
CosmoSQLClient.MsSql.EntityFrameworkCore |
UseCosmoSqlServer(...) |
CosmoSQLClient.Postgres |
CosmoSQLClient.Postgres.EntityFrameworkCore |
UseCosmoPostgres(...) |
CosmoSQLClient.MySql |
CosmoSQLClient.MySql.EntityFrameworkCore |
UseCosmoMySql(...) |
CosmoNova.Engine.Sqlite |
CosmoSQLClient.Sqlite.EntityFrameworkCore (legacy, pre-6.x only) |
UseCosmoSqlite(...) |
Quick Start
Basic Query (MSSQL)
using CosmoSQLClient.MsSql;
var connStr = "Server=localhost;Database=Sales;User Id=sa;Password=your_password;";
await using var conn = await MsSqlConnection.OpenAsync(connStr);
await using var cmd = conn.CreateCommand("SELECT TOP 10 * FROM Invoices");
await using var reader = await cmd.ExecuteReaderAsync();
while (await reader.ReadAsync())
{
var total = reader.GetDecimal("TotalAmount");
Console.WriteLine($"Invoice Total: {total}");
}
Embedded T-SQL (CosmoKv)
using CosmoSQLClient.CosmoKv;
using CosmoSQLClient.Core;
await using var conn = await CosmoKvConnection.OpenAsync(
new CosmoKvConfiguration { DataSource = "/var/lib/app/db" });
await conn.ExecuteAsync("""
CREATE TABLE IF NOT EXISTS Users (
Id BIGINT IDENTITY PRIMARY KEY,
Email NVARCHAR(256) NOT NULL,
CreatedAt DATETIME2 NOT NULL DEFAULT GETUTCDATE())
""");
// INSERT … OUTPUT returns the just-allocated IDENTITY.
var inserted = await conn.QueryAsync(
"INSERT INTO Users (Email) OUTPUT INSERTED.Id VALUES (@e)",
new[] { SqlParameter.Named("@e", SqlValue.From("alice@d.com")) });
long newId = inserted[0]["Id"].AsInt() ?? 0;
// INNER JOIN with qualified column refs.
var rows = await conn.QueryAsync(
"SELECT u.Email FROM Users u JOIN Mailboxes m ON m.UserId = u.Id");
Advanced Streaming (IAsyncEnumerable)
Rows are yielded as they arrive from the socket, ensuring the full result set is never buffered in memory.
await foreach (var row in conn.Advanced.QueryStreamAsync("SELECT * FROM LargeTable"))
{
var id = row["Id"].AsInt32();
// Process one row at a time
}
Entity Framework Core
CosmoSQLClient can be used as the underlying DbConnection for the standard EF Core relational providers. Install the matching EF Core bridge package, then configure your DbContext with the Cosmo-specific extension for that database.
using Microsoft.EntityFrameworkCore;
services.AddDbContext<AppDbContext>(options =>
options.UseCosmoSqlServer("Server=localhost;Database=Sales;User Id=sa;Password=your_password;TrustServerCertificate=True;"));
services.AddDbContext<AppDbContext>(options =>
options.UseCosmoPostgres("Host=localhost;Database=Sales;User Id=postgres;Password=your_password;"));
services.AddDbContext<AppDbContext>(options =>
options.UseCosmoMySql(
"Host=localhost;Database=Sales;User Id=root;Password=your_password;",
new MySqlServerVersion(new Version(8, 0, 0))));
CLI: cosmokv
A sqlite3-style shell for CosmoKv embedded databases — REPL, one-shot SQL, stdin scripts, and four output formats. Ships as a dotnet global tool.
dotnet tool install -g CosmoSQLClient.CosmoKv.Cli
cosmokv ./mydb # REPL
cosmokv ./mydb "SELECT * FROM Users" # one-shot
cat schema.sql | cosmokv ./mydb - # stdin script
cosmokv --format=json ./mydb "SELECT * FROM Users" # JSON output
REPL dot-commands cover the usual introspection surface (.tables, .schema [TABLE], .indexes [TABLE], .dump, .format FMT, .quit). Full reference: src/CosmoSQLClient.CosmoKv.Cli/README.md.
The introspection used by .schema / .dump is also available programmatically from v2.5 — CosmoKvConnection.GetTableNames(), GetTableScript(name), GetIndexScriptsForTable(name), ScriptSchema() — so you can build your own dump/backup tooling without going through the CLI.
Technical Architecture
Zero-Allocation Pipeline
CosmoSQLClient implements a generic protocol decoder (ProcessTokensAsync) using struct handlers. This architecture ensures:
- No Boxing:
SqlRowandSqlValuetypes are never cast toobjectduring decoding. - JIT Devirtualization: The row-parsing path is inlined by the .NET JIT compiler, removing interface dispatch overhead.
- Minimal Heap Pressure: Bounded memory footprint regardless of result set size.
Package Size Comparison
CosmoSQLClient avoids heavy dependencies like Azure.Identity, MSAL, or Microsoft.Data.SqlClient.SNI.
| Library | Published Footprint |
|---|---|
| CosmoSQLClient.MsSql | ~207 KB |
| Microsoft.Data.SqlClient | ~17 MB+ |
SqlValue Type Mapping
SqlValue is the universal cell type returned by advanced query methods. It wraps the raw wire value and provides typed accessors:
SqlValue Accessor |
.NET Type |
|---|---|
AsInt32() / AsInt64() |
int / long |
AsString() |
string |
AsDecimal() |
decimal |
AsDouble() / AsFloat() |
double / float |
AsBoolean() |
bool |
AsDateTime() / AsDateTimeOffset() |
DateTime / DateTimeOffset |
AsGuid() |
Guid |
AsBytes() |
byte[] |
IsNull |
bool |
Advanced Usage
Integrated Security (MSSQL)
Supports native NTLMv2 authentication for Windows/Linux environments without external dependencies.
var connStr = "Server=myserver;Integrated Security=SSPI;Trust Server Certificate=true;";
await using var conn = await MsSqlConnection.OpenAsync(connStr);
JSON Streaming
Stream query results directly to a PipeWriter or Stream as JSON with zero intermediate allocations.
await conn.Advanced.QueryJsonStreamAsync(
"SELECT * FROM Users",
pipeWriter,
format: JsonOutputFormat.Array);
Stored Procedures (MSSQL)
var result = await conn.Advanced.ExecuteProcAsync("GetCustomerInvoices", new {
CustomerId = 123,
Year = 2024
});
Related Projects
- CosmoSQLClient-Swift — Swift NIO port of CosmoSQLClient with the same API design and wire-protocol implementations for server-side Swift.
- SQLClient-Swift — The original MSSQL driver using FreeTDS (predecessor to the Swift port).
License
Licensed under the MIT License.
| 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
- CosmoSQLClient.MsSql (>= 7.31.0)
- Microsoft.EntityFrameworkCore.SqlServer (>= 10.0.9)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.9)
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 |
|---|---|---|
| 7.31.0 | 0 | 7/31/2026 |
| 7.30.0 | 0 | 7/30/2026 |
| 7.29.0 | 0 | 7/30/2026 |
| 7.28.0 | 0 | 7/30/2026 |
| 7.27.0 | 0 | 7/30/2026 |
| 7.26.0 | 0 | 7/30/2026 |
| 7.25.0 | 0 | 7/30/2026 |
| 7.24.0 | 6 | 7/30/2026 |
| 7.23.0 | 43 | 7/30/2026 |
| 7.22.0 | 46 | 7/29/2026 |
| 7.21.0 | 45 | 7/29/2026 |
| 7.20.0 | 49 | 7/29/2026 |
| 7.19.0 | 45 | 7/29/2026 |
| 7.18.0 | 44 | 7/29/2026 |
| 7.17.0 | 44 | 7/28/2026 |
| 7.16.0 | 49 | 7/28/2026 |
| 7.15.0 | 40 | 7/28/2026 |
| 7.14.0 | 43 | 7/28/2026 |
| 7.13.0 | 47 | 7/28/2026 |
| 7.12.0 | 52 | 7/27/2026 |