Watch Aspire live streamsDocsTry Aspire

SQLite Entity Framework Core integration

⭐ Community Toolkit SQLite logo

The Aspire Community Toolkit SQLite Entity Framework Core integration registers a pooled DbContext against a SQLite database. It can also add health checks and EF Core tracing to a context that the app has already registered.

Use this package in the consuming .NET app. It does not create an AppHost resource or start a database server. For ADO.NET SqliteConnection registration instead of EF Core, see Connect to SQLite.

Install 📦 CommunityToolkit.Aspire.Microsoft.EntityFrameworkCore.Sqlite in the project that uses the context:

.NET CLI — Add CommunityToolkit.Aspire.Microsoft.EntityFrameworkCore.Sqlite package
dotnet add package CommunityToolkit.Aspire.Microsoft.EntityFrameworkCore.Sqlite

Provide a DbContext implementation and either a referenced SQLite file resource or a configured SQLite connection string.

Install the SQLite hosting integration in the AppHost. Add a file resource named sqlite, then reference it from an ASP.NET Core project named Api. Add a project reference in the C# AppHost to generate Projects.Api.

apphost.mts
import { createBuilder } from './.aspire/modules/aspire.mjs';
const builder = await createBuilder();
const sqlite = await builder.addSqlite('sqlite');
const api = await builder.addProject('api', '../Api/Api.csproj');
await api.withReference(sqlite);
await builder.build().run();

The hosting resource’s connection string is Data Source={databaseFilePath};Cache=Shared;Mode=ReadWriteCreate. Aspire injects it as ConnectionStrings__sqlite; .NET reads it from ConnectionStrings:sqlite. The reference also supplies SQLITE_DATASOURCE, containing only the file path.

The EF Core integration reads the named connection string, not SQLITE_DATASOURCE. Keep the connection name passed to registration identical to the resource name.

Call AddSqliteDbContext<TContext> to register a context through AddDbContextPool. The context is resolved as a scoped service and its instances are pooled.

This complete development example creates the schema and exposes a query endpoint:

Program.cs
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Hosting;
var builder = WebApplication.CreateBuilder(args);
builder.AddSqliteDbContext<NotesContext>("sqlite");
var app = builder.Build();
using (var scope = app.Services.CreateScope())
{
var context = scope.ServiceProvider.GetRequiredService<NotesContext>();
await context.Database.EnsureCreatedAsync();
}
app.MapGet("/notes", async (NotesContext context) =>
await context.Notes.AsNoTracking().ToListAsync());
app.Run();
public sealed class NotesContext(DbContextOptions<NotesContext> options)
: DbContext(options)
{
public DbSet<Note> Notes => Set<Note>();
}
public sealed class Note
{
public int Id { get; set; }
public string Text { get; set; } = "";
}

Registration configures UseSqlite with the resolved connection string. It does not apply migrations, seed data, or create application tables. Do not register the same context separately before calling this API.

Use EnrichSqliteDatabaseDbContext<TDbContext> when the application already owns its context registration. Register and configure the SQLite provider first:

Program.cs
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Hosting;
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("sqlite")
?? throw new InvalidOperationException("ConnectionStrings:sqlite is required");
builder.Services.AddDbContext<NotesContext>(options =>
options.UseSqlite(connectionString));
builder.EnrichSqliteDatabaseDbContext<NotesContext>();
var app = builder.Build();
using (var scope = app.Services.CreateScope())
{
var context = scope.ServiceProvider.GetRequiredService<NotesContext>();
await context.Database.EnsureCreatedAsync();
}
app.MapGet("/notes", async (NotesContext context) =>
await context.Notes.AsNoTracking().ToListAsync());
app.Run();
public sealed class NotesContext(DbContextOptions<NotesContext> options)
: DbContext(options)
{
public DbSet<Note> Notes => Set<Note>();
}
public sealed class Note
{
public int Id { get; set; }
public string Text { get; set; } = "";
}

Enrichment checks that the context is registered and adds the integration’s health checks and tracing. It does not register a context, select a connection name, replace the connection string, enable pooling, or configure retries.

The exported overload takes only an optional Action<SqliteEntityFrameworkCoreSettings> after the builder. To disable tracing, use settings => settings.DisableTracing = true; there is no connection-name or enableOpenTelemetry parameter on this method.

For an app running without the AppHost, configure the same name used by AddSqliteDbContext:

appsettings.json
{
"ConnectionStrings": {
"sqlite": "Data Source=C:\\Data\\notes.db"
}
}

See Microsoft.Data.Sqlite connection strings for supported provider options.

The settings section is Aspire:Sqlite:EntityFrameworkCore:Sqlite. Context-specific settings use the context’s simple type name beneath that section:

appsettings.json
{
"Aspire": {
"Sqlite": {
"EntityFrameworkCore": {
"Sqlite": {
"ConnectionString": "Data Source=C:\\Data\\notes.db",
"DisableHealthChecks": false,
"DisableTracing": false,
"NotesContext": {
"DisableTracing": true
}
}
}
}
}
}

For registration, the integration reads the base and context-specific settings, then replaces ConnectionString with the named ConnectionStrings value if present. The inline settings delegate runs last. Connection-string validation is delayed until the context is requested.

Enrichment binds settings for instrumentation but leaves the existing context’s database options unchanged.

The registration API accepts a settings delegate and a DbContextOptionsBuilder delegate. The options delegate runs after UseSqlite:

Program.cs
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Hosting;
var builder = WebApplication.CreateBuilder(args);
builder.AddSqliteDbContext<NotesContext>(
"sqlite",
configureSettings: settings => settings.DisableTracing = true,
configureDbContextOptions: options =>
options.UseSqlite(sqlite => sqlite.CommandTimeout(30)));
var app = builder.Build();
app.MapGet("/database-ready", async (NotesContext context) =>
await context.Database.CanConnectAsync());
app.Run();
public sealed class NotesContext(DbContextOptions<NotesContext> options)
: DbContext(options)
{
}

This sets a provider command timeout of 30 seconds. SqliteEntityFrameworkCoreSettings exports ConnectionString, DisableHealthChecks, DisableTracing, and DefaultTimeout. Both disable flags default to false.

There is no keyed-context registration API. Use distinct context types for independently configured databases.

Unless disabled, the integration registers AddDbContextCheck<TContext> using the context’s simple type name as the check name. The default EF Core check calls Database.CanConnectAsync to verify database connectivity. It does not prove that migrations or application tables exist.

Set DisableHealthChecks=true through configuration or either API’s settings delegate to omit the check. Use service defaults to map the registered checks to HTTP endpoints.

Unless DisableTracing is true, the integration registers EF Core OpenTelemetry instrumentation. Configure exporters, for example through service defaults, to view EF Core traces in the dashboard.

The integration does not register a metrics meter, logging provider, or retry policy. EF Core uses normal .NET logging. Configure database logging through the application’s logging settings.

This client package is .NET-specific. TypeScript AppHost support applies to the referenced SQLite hosting resource, not to EF Core context registration.