CodeLogic.SQLite
4.5.2-preview.68
See the version list below for details.
dotnet add package CodeLogic.SQLite --version 4.5.2-preview.68
NuGet\Install-Package CodeLogic.SQLite -Version 4.5.2-preview.68
<PackageReference Include="CodeLogic.SQLite" Version="4.5.2-preview.68" />
<PackageVersion Include="CodeLogic.SQLite" Version="4.5.2-preview.68" />
<PackageReference Include="CodeLogic.SQLite" />
paket add CodeLogic.SQLite --version 4.5.2-preview.68
#r "nuget: CodeLogic.SQLite, 4.5.2-preview.68"
#:package CodeLogic.SQLite@4.5.2-preview.68
#addin nuget:?package=CodeLogic.SQLite&version=4.5.2-preview.68&prerelease
#tool nuget:?package=CodeLogic.SQLite&version=4.5.2-preview.68&prerelease
CodeLogic.SQLite
SQLite database library for CodeLogic with connection pooling, a fluent LINQ-shaped query builder, attribute-driven table sync, and migration tracking. Built on Microsoft.Data.Sqlite.
Install
dotnet add package CodeLogic.SQLite
Quick start
await Libraries.LoadAsync<SQLiteLibrary>();
var sqlite = Libraries.Get<SQLiteLibrary>();
// 1. Sync the table from the entity (CREATE / ALTER to match the class)
await sqlite.TableSync.SyncTableAsync<NoteRecord>("Default");
// 2. CRUD via the repository — every call returns a Result<T>
var repo = sqlite.GetRepository<NoteRecord>("Default");
var insert = await repo.InsertAsync(new NoteRecord { Title = "Hello", Body = "World" });
if (insert.IsSuccess)
Console.WriteLine($"new rowid = {insert.Value}");
// 3. Fluent queries via the query builder
var notes = await sqlite.GetQueryBuilder<NoteRecord>("Default")
.Where(n => n.Title.Contains("Hello"))
.OrderByDescending(n => n.CreatedUtc)
.Take(20)
.ToListAsync();
foreach (var note in notes.Value)
Console.WriteLine(note.Title);
The entity is plain C# annotated with [SQLiteTable] / [SQLiteColumn]:
[SQLiteTable("notes")]
public sealed class NoteRecord
{
[SQLiteColumn(IsPrimaryKey = true, IsAutoIncrement = true)]
public long Id { get; set; }
[SQLiteColumn(ColumnName = "title", IsNotNull = true, IsIndexed = true)]
public string Title { get; set; } = "";
[SQLiteColumn(ColumnName = "body")]
public string Body { get; set; } = "";
[SQLiteColumn(ColumnName = "created_utc")]
public DateTime CreatedUtc { get; set; } = DateTime.UtcNow;
}
Only properties marked with
[SQLiteColumn]are mapped — unannotated properties are ignored for schema, reads, and writes. The connection id defaults to"Default"on every entry point, soGetRepository<NoteRecord>()is equivalent toGetRepository<NoteRecord>("Default").
What's in the box
Library entry points
| Member | Purpose |
|---|---|
GetRepository<T>(connectionId = "Default") |
CRUD + raw SQL for an entity |
GetQueryBuilder<T>(connectionId = "Default") |
fluent query builder |
TableSync |
SyncTableAsync<T>, SyncTablesAsync, SyncNamespaceAsync |
MigrationTracker |
inspect applied schema migrations |
ConnectionManager |
named connection pool (active/pooled counts, test) |
HealthCheckAsync() |
per-database connectivity check (Healthy / Degraded / Unhealthy) |
All data operations return CodeLogic Result / Result<T> — check .IsSuccess and read .Value, or inspect .Error. They do not throw on query failure.
Repository
GetRepository<T>() exposes:
| Method | Result |
|---|---|
InsertAsync(entity) |
Result<long> — new rowid; auto-increment PK is written back to the entity |
UpsertAsync(entity) |
INSERT OR REPLACE |
UpdateAsync(entity) |
update by primary key |
DeleteAsync(id) |
delete by single PK |
GetByIdAsync(id) |
Result<T?> |
GetByKeysAsync(ct, params keys) |
composite-PK lookup |
DeleteByKeysAsync(ct, params keys) |
composite-PK delete |
GetAllAsync(limit = 1000) |
Result<List<T>> |
FindAsync(predicate) |
Result<List<T>> from a LINQ WHERE |
CountAsync() |
Result<long> |
GetPagedAsync(page, pageSize, orderBy?, desc?) |
Result<PagedResult<T>> |
RawQueryAsync(sql, params?) |
Result<List<T>> — raw SELECT mapped to entities |
RawExecuteAsync(sql, params?) |
Result<int> — raw non-query, rows affected |
var repo = sqlite.GetRepository<NoteRecord>();
var page = await repo.GetPagedAsync(page: 1, pageSize: 20, orderBy: "created_utc", desc: true);
var byTag = await repo.FindAsync(n => n.Title.StartsWith("draft"));
var raw = await repo.RawQueryAsync(
"SELECT * FROM notes WHERE title LIKE @q",
new() { ["@q"] = "%hello%" });
Always bind values via named parameters — never interpolate user input into the SQL.
Fluent query builder
GetQueryBuilder<T>() chains LINQ-shaped clauses and translates them to SQL.
| Capability | Shape |
|---|---|
| Filter | .Where(x => x.Status == "active" && x.Age >= 18) (multiple calls AND together) |
| Sort | .OrderBy, .OrderByDescending, .ThenBy, .ThenByDescending |
| Paging | .Limit / .Take, .Offset / .Skip, .ToPagedListAsync |
| Projection | .Select(x => new { x.Id, x.Title }) — restricts the SELECT column list |
| Grouping | .GroupBy(x => x.Category) |
Terminal operations (each returns a Result):
| Method | Result |
|---|---|
ToListAsync() |
Result<List<T>> |
FirstOrDefaultAsync() |
Result<T?> |
ToPagedListAsync(page, pageSize) |
Result<PagedResult<T>> |
CountAsync() |
Result<long> over the current WHERE |
SumAsync(x => x.Col) / MaxAsync / MinAsync |
Result<TResult> aggregate |
DeleteAsync() |
Result<int> — bulk delete by predicate |
UpdateAsync(Dictionary<string, object?>) |
Result<int> — bulk update by predicate |
var qb = sqlite.GetQueryBuilder<NoteRecord>();
var total = await qb.Where(n => n.Title.Contains("hello")).CountAsync();
var page = await sqlite.GetQueryBuilder<NoteRecord>()
.Where(n => n.CreatedUtc >= since)
.OrderByDescending(n => n.CreatedUtc)
.ToPagedListAsync(page: 1, pageSize: 20);
// Bulk predicate mutations
await sqlite.GetQueryBuilder<NoteRecord>()
.Where(n => n.CreatedUtc < cutoff)
.DeleteAsync();
await sqlite.GetQueryBuilder<NoteRecord>()
.Where(n => n.Title == "")
.UpdateAsync(new() { ["title"] = "(untitled)" });
Attribute-driven schema sync
Entity classes are the source of truth. TableSync.SyncTableAsync<T>() creates or alters the SQLite table to match the class; SyncTablesAsync and SyncNamespaceAsync batch-sync many types.
| Attribute | Purpose |
|---|---|
[SQLiteTable("name")] |
table name (defaults to the class name) |
[SQLiteColumn] |
ColumnName, DataType, Size, IsPrimaryKey, IsAutoIncrement, IsIndexed, IsUnique, IsNotNull, DefaultValue |
[SQLiteIndex(cols...)] |
class-level named index; IsUnique, Name |
[SQLiteForeignKey(table, column)] |
FK with OnDelete / OnUpdate (ForeignKeyAction: NoAction, Restrict, SetNull, SetDefault, Cascade) |
SQLiteDataType values: INTEGER, REAL, TEXT, BLOB, NUMERIC, DATETIME, DATE, BOOLEAN, UUID. When omitted the type is inferred from the property type. bool, DateTime, DateTimeOffset, Guid, and enum are converted automatically on read and write.
[SQLiteTable("orders")]
[SQLiteIndex("customer_id", "created_utc", Name = "ix_orders_customer")]
public sealed class OrderRecord
{
[SQLiteColumn(IsPrimaryKey = true, IsAutoIncrement = true)]
public long Id { get; set; }
[SQLiteColumn(ColumnName = "customer_id", IsNotNull = true)]
[SQLiteForeignKey("customers", "id", OnDelete = ForeignKeyAction.Cascade)]
public long CustomerId { get; set; }
[SQLiteColumn(ColumnName = "total", DataType = SQLiteDataType.NUMERIC)]
public decimal Total { get; set; }
[SQLiteColumn(ColumnName = "created_utc")]
public DateTime CreatedUtc { get; set; } = DateTime.UtcNow;
}
Observability
Queries are logged when the runtime is in development mode, and any query that runs longer than the per-database SlowQueryThresholdMs is logged as a warning.
Configuration
Auto-generated on first run under data/codelogic/Libraries/CL.SQLite/config.sqlite.json. The config is a map of named databases — each key is a connection id you pass to GetRepository / GetQueryBuilder / SyncTableAsync.
{
"databases": {
"Default": {
"enabled": true,
"databasePath": "database.db",
"connectionTimeoutSeconds": 30,
"commandTimeoutSeconds": 120,
"skipTableSync": false,
"cacheMode": "default",
"useWAL": true,
"enableForeignKeys": true,
"maxPoolSize": 10,
"slowQueryThresholdMs": 500
}
}
}
| Field | Default | Purpose |
|---|---|---|
enabled |
true |
disable a database without removing it |
databasePath |
database.db |
absolute, or relative to the library data directory |
connectionTimeoutSeconds |
30 |
connection open timeout |
commandTimeoutSeconds |
120 |
per-command timeout |
skipTableSync |
false |
turn off automatic schema sync for this database |
cacheMode |
default |
default / private / shared |
useWAL |
true |
Write-Ahead Logging — better concurrency, recommended |
enableForeignKeys |
true |
enforce FK constraints |
maxPoolSize |
10 |
max pooled connections |
slowQueryThresholdMs |
500 |
slow-query warning threshold |
A database with enabled: false is skipped at startup; if no database is enabled the library initializes in a disabled state and the health check reports healthy-but-disabled.
Documentation
Requirements
- CodeLogic 3.x or 4.x | .NET 10
License
MIT — see 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
- CodeLogic (>= 3.2.0 && < 5.0.0)
- Microsoft.Data.Sqlite (>= 9.0.17)
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 |
|---|---|---|
| 4.6.72 | 48 | 6/20/2026 |
| 4.6.69-preview | 38 | 6/20/2026 |
| 4.5.2 | 109 | 5/24/2026 |
| 4.5.2-preview.68 | 63 | 6/20/2026 |
| 4.5.1 | 107 | 5/24/2026 |
| 4.5.1-preview.56 | 62 | 5/24/2026 |
| 4.4.2-preview.53 | 60 | 5/24/2026 |
| 4.4.1 | 105 | 5/24/2026 |
| 4.0.5 | 103 | 5/15/2026 |
| 4.0.4 | 113 | 5/9/2026 |
| 4.0.3 | 104 | 5/9/2026 |
| 4.0.1 | 115 | 4/19/2026 |
| 3.3.1 | 113 | 4/18/2026 |
| 3.3.0 | 104 | 4/18/2026 |
| 3.2.11 | 106 | 4/18/2026 |
| 3.2.10 | 106 | 4/18/2026 |
| 3.2.9 | 109 | 4/18/2026 |
| 3.2.8 | 107 | 4/18/2026 |
| 3.2.7 | 103 | 4/18/2026 |
| 3.2.6 | 110 | 4/18/2026 |
# CL.SQLite — Changelog
All notable changes to **CodeLogic.SQLite** are documented here. Versions follow
[Semantic Versioning](https://semver.org/).
## [4.5.2] — 2026-06-20
### Documentation
- Corrected the README to match the shipping API: the query builder is obtained
via `GetQueryBuilder<T>()` (there is no `sqlite.Query<T>()`), all data
operations return `Result` / `Result<T>`, and entities require
`[SQLiteTable]` / `[SQLiteColumn]` annotations. The previous Quick Start no
longer compiled.
- Documented the configuration as the real `databases` map (per-named-database
`databasePath`, `useWAL`, `cacheMode`, `maxPoolSize`, `slowQueryThresholdMs`,
timeouts, `skipTableSync`, `enableForeignKeys`), replacing the inaccurate
`connections` array with `journalMode`/`poolSize`.
- Documented previously undocumented user-facing surface that already shipped:
the full query builder (`Select`, `GroupBy`, `Sum`/`Max`/`Min`, predicate
`DeleteAsync`/`UpdateAsync`, `ToPagedListAsync`), repository `UpsertAsync`,
composite-key (`GetByKeysAsync`/`DeleteByKeysAsync`), `GetPagedAsync`, raw SQL
(`RawQueryAsync`/`RawExecuteAsync`), attribute-driven schema sync
(`SyncTableAsync`/`SyncTablesAsync`/`SyncNamespaceAsync` with
`[SQLiteIndex]`/`[SQLiteForeignKey]`), and the `MigrationTracker`. No code
changes — documentation only.
## [4.5.0] — 2026-05-24
### Changed
- **Unified versioning.** All CodeLogic.Libs now share a single version line
controlled by `version.txt` in the repo root. This is a version alignment
release — no functional changes to this library.
## [4.0.4] — 2026-04-16
### Changed
- README + manifest refresh for the v4 baseline. No functional changes vs 4.0.3.
- `LibraryManifest.Version` now reads from assembly metadata.
## [4.0.3] — 2026-04-16
### Fixed
- Added missing `<param name="connectionId">` XML doc tags so the public API
no longer trips doc-warning gates.
## [4.0.2] — 2026-04-09
### Changed
- Annotated SQLite configuration with `[ConfigField]` for the admin UI surface.
- Aligned with the v4 baseline across all libraries.
## [4.0.0] — 2026-04-09
Major rewrite. Republished as v4.0.0 to reset the version line under the
unified v4 baseline. Embedded-DB sibling of CL.MySQL2 with the same
repository pattern and attribute-driven schema sync.
### Notes
- The MySQL2 4.0 query-builder rewrite (projection pushdown, SQL aggregation,
smart-cache pools) has not been ported to CL.SQLite yet — repository
CRUD only.
- Earlier history is retained in the
[git log](https://github.com/Media2A/CodeLogic.Libs/commits/main/CL.SQLite).