Sharc is not a drop-in replacement, but migrating read paths is straightforward.
Before (Microsoft.Data.Sqlite):
using var conn = new SqliteConnection("Data Source=mydb.db");
conn.Open();After (Sharc):
using var db = SharcDatabase.Open("mydb.db");No connection strings. No Open() call. SharcDatabase.Open() reads the header and is ready immediately.
Before:
using var cmd = conn.CreateCommand();
cmd.CommandText = "SELECT id, name FROM users";
using var reader = cmd.ExecuteReader();
while (reader.Read())
{
long id = reader.GetInt64(0);
string name = reader.GetString(1);
}After:
using var reader = db.CreateReader("users", "id", "name");
while (reader.Read())
{
long id = reader.GetInt64(0);
string name = reader.GetString(1);
}Column access uses ordinal indices (0-based), matching the order of the projection you specified. No SQL parsing, no prepared statements.
Before:
cmd.CommandText = "SELECT * FROM users WHERE id = $id";
cmd.Parameters.AddWithValue("$id", 42);
using var reader = cmd.ExecuteReader();
if (reader.Read()) { /* found */ }After:
using var reader = db.CreateReader("users");
if (reader.Seek(42)) { /* found in < 1 us */ }This is where Sharc's advantage is largest: 7-61x faster than the SQL path.
Before:
cmd.CommandText = "SELECT * FROM users WHERE age >= 18 AND status = 'active'";After:
var filter = FilterStar.And(
FilterStar.Column("age").Gte(18L),
FilterStar.Column("status").Eq("active")
);
using var reader = db.CreateReader("users", filter);Before:
cmd.CommandText = "PRAGMA table_info('users')";
using var reader = cmd.ExecuteReader();After:
var table = db.Schema.Tables.First(t => t.Name == "users");
foreach (var col in table.Columns)
Console.WriteLine($"{col.Name}: {col.TypeAffinity}");Sharc uses specific exception types instead of generic SqliteException:
| Exception | When |
|---|---|
InvalidDatabaseException |
File is not a valid SQLite format 3 database |
CorruptPageException |
B-tree page has invalid structure |
SharcCryptoException |
Decryption failed (wrong password, tampered data) |
UnsupportedFeatureException |
Valid SQLite feature not supported by Sharc |
All are in the Sharc.Exceptions namespace.
Before:
using var conn = new SqliteConnection("Data Source=:memory:");After:
byte[] dbBytes = File.ReadAllBytes("mydb.db");
using var db = SharcDatabase.OpenMemory(dbBytes);Sharc's in-memory mode reads from a byte array, not a connection string. This is useful for cloud blobs, embedded resources, or network-delivered databases.
- File format: Sharc reads the same
.dbfiles that SQLite creates. No conversion needed. - Column types: INTEGER, REAL, TEXT, BLOB, NULL — same type system.
- Threading: Multiple readers work in parallel, same as SQLite in WAL mode.
| Aspect | Microsoft.Data.Sqlite | Sharc |
|---|---|---|
| SQL queries | Full SQL support | No SQL — raw B-tree reads |
| Dependencies | Requires e_sqlite3 native DLL |
Zero native dependencies |
| Column access | By ordinal or name | By ordinal only |
| Seek performance | ~20-40 us (via SQL) | ~0.4-1.5 us (direct B-tree) |
| Package size | ~2 MB | ~250 KB |
After migrating read workloads:
| Operation | Expected Improvement |
|---|---|
| Point lookups | 7-61x faster |
| Sequential scans | 2-4x faster |
| Schema reads | 5-13x faster |
| Batch lookups | 40-66x faster |
| Memory allocation | Parity or less |