Write LINQ.
Query SQLite.

Typed tables, async queries and a familiar EF-style API that translates your whole IQueryable to SQL. Built for MAUI, Avalonia and Native AOT.

dotnet add package SQLite.Framework

.NET 8, 9, 10Native AOT readyMIT licensed

No. 01 Program.cs C#
var options = new SQLiteOptionsBuilder("books.db")
    .UseMinimumSqliteVersion(SQLiteMinimumVersion.V3_36)
    .Build();

using SQLiteDatabase db = new(options);

var topAuthors = await (
    from b in db.Table<Book>()
    join a in db.Table<Author>() on b.AuthorId equals a.Id
    where b.Price < 30
    group b by a.Name into g
    orderby g.Sum(b => b.Sales) descending
    select new
    {
        Author = g.Key,
        Titles = g.Count(),
        Revenue = g.Sum(b => b.Sales),
    }
).Take(5).ToListAsync();

You write LINQ. It ships SQL.

Your query is read and turned into plain SQLite SQL. Pick a feature to see the SQL it generates.

C# LINQ query
var topAuthors = await (
    from b in db.Table<Book>()
    join a in db.Table<Author>()
        on b.AuthorId equals a.Id
    where b.Price < 30
    group b by a.Name into g
    orderby g.Sum(b => b.Sales) descending
    select new
    {
        Author = g.Key,
        Titles = g.Count(),
        Revenue = g.Sum(b => b.Sales),
    }
).Take(5).ToListAsync();
SQL Generated SQLite
SELECT a0."AuthorName" AS "Author",
       COUNT(*) AS "Titles",
       SUM(b0."BookSales") AS "Revenue"
FROM "Books" AS b0
INNER JOIN "Authors" AS a0
    ON b0."BookAuthorId" = a0."AuthorId"
WHERE b0."BookPrice" < @p0
GROUP BY a0."AuthorName"
ORDER BY SUM(b0."BookSales") DESC
LIMIT @p1;

Built for real apps

Everything you expect from a modern ORM, sized for embedded SQLite.

LINQ first

Full IQueryable support. Joins, group by, subqueries, window functions and CTEs all translate to SQL.

Async everywhere

Every operation has an async sibling. ToListAsync, FirstOrDefaultAsync, ExecuteUpdateAsync and more.

Native AOT

The framework never generates code at runtime. An optional source generator emits materializers at build time, so it ships clean under Native AOT.

FTS5 and R-Tree

First-class bindings for SQLite's full-text search and spatial modules. Type-safe, no raw SQL needed.

JSON and JSONB

Query into JSON columns with LINQ. SQLite 3.45 JSONB is supported when your runtime has it.

Bulk operations

ExecuteDelete and ExecuteUpdate let you change thousands of rows in one round trip.

No code generated at runtime

How does a typed query work without emitting code at runtime?

  1. You write LINQ

    A normal query against a typed table. The C# compiler turns it into an expression tree.

  2. The tree becomes SQL

    The framework walks that expression tree and writes plain SQLite SQL with bound parameters. No IL is emitted.

  3. SQLite returns rows

    The SQL runs and SQLite hands back a row reader.

  4. A materializer fills your objects

    A small reader maps each column to a property and builds your object using Method.Invoke and PropertyInfo.SetValue. No Reflection.Emit, no runtime code generation.

Want the framework to be AOT safe? The optional source generator writes those materializers at build time, so there is no reflection on your hot path and the trimmer keeps every type. Read about the source generator

Save Pace Stream

Each dot is one save of 100 rows. The gap before the next dot is how long that save took. The times come from real BenchmarkDotNet runs.

EF Core 10 AddRange + SaveChanges SQLite.Framework AddRange
TIME 15x faster EF Core SQLite.Framework

How it compares

Where SQLite.Framework sits next to EF Core and sqlite-net-pcl. Based on the default setup of each library.

Feature SQLite.Framework EF Core 10 sqlite-net-pcl
LINQ IQueryable translation Yes Yes No
Select projection to SQL Yes Yes No
Async API Yes Yes Yes
Native AOT ready Yes No Partial
Bulk update and delete by predicate Yes Yes No
Full text search (FTS5) Yes No Partial
JSON columns Yes Yes No
Window functions and CTEs Yes Partial No
Encryption (SQLCipher) Yes No Yes
Change tracking and migrations Partial Yes No

One API, four flavors

Pick the package that matches how SQLite is shipped in your app.

SQLite.Framework

Uses the SQLite version that ships with the OS. The right default for most apps.

SQLite.Framework.Bundled

Ships its own SQLite binary. Use when the OS SQLite is too old or you want a pinned version.

SQLite.Framework.Cipher

Uses SQLCipher for encrypted databases. Call UseEncryptionKey on the options builder to enable.

SQLite.Framework.Base

No provider included. Bring your own SQLitePCLRaw bundle and stay in control.

Questions

Does it support Native AOT?

Yes. The framework never generates code at runtime. Add the optional source generator and call UseGeneratedMaterializers. Queries run with no reflection on the materialization path, so the trimmer keeps every type. See Native AOT.

Is it safe to use from multiple threads?

Yes. Create one SQLiteDatabase and share it across the app. Commands take a connection lock automatically. Turn on WAL mode so reads and writes do not block each other. See Multi-threading.

Can I encrypt the database?

Yes. Use the SQLite.Framework.Cipher package, which ships SQLCipher. Call UseEncryptionKey on the options builder.

Which .NET and SQLite versions are supported?

.NET 8, 9 and 10. It uses the SQLite that ships with your OS by default. You can set a minimum version on the builder or ship a pinned binary with the Bundled package.

Does it have a change tracker or migrations?

It does not have a change tracker like EF Core. That is by design. It has lightweight stand-ins instead. Write hooks (OnAdd and OnUpdate) run before a save for audit and derived values. A versioned migration runner reconciles and versions the schema. There is no automatic change tracker, unit of work or lazy loading.

How is it different from EF Core or sqlite-net-pcl?

It translates full LINQ, including Select projections, to SQL like EF Core, but stays light and AOT friendly. Unlike sqlite-net-pcl it does not read whole rows into memory to run a projection. See Migrating from EF Core and Migrating from sqlite-net-pcl.

Ready to try it?

Pick the host you ship on and step through a guided setup. Console, MAUI, Avalonia, ASP.NET or Blazor.