Platform · Files
The database as a file
IBsqliteStorageAdmin treats a database as an artifact rather than a
connection: what exists, read the bytes out, write bytes back, delete. Cross-provider
migration and the diagnostics on Storage are built from this same
surface, and none of it goes through EF.
Fastest persistent tier. Real files in the origin private file system. Concurrent connections, no COOP/COEP.
What each backend holds
Names come from the provider, so a backend that has never been used reports empty
rather than failing. Related -journal files are not databases and do
not appear.
// Databases as files, outside any SQL connection. No EF involved.
foreach (var provider in Database.Providers)
{
IReadOnlyList<string> names = await provider.Admin.ListAsync();
}Download a real .db
Exports app.db from whichever backend currently
owns it. On OPFS that is a file read; on IndexedDB and Cache Storage the image is
assembled from pages. Either way the result is an ordinary SQLite file.
var session = await Database.EnsureSessionAsync();
var provider = session.Resolution.Provider;
byte[] image = await provider.Admin.ExportAsync("app.db");
// A plain SQLite file: open it in any desktop tool.
await js.InvokeVoidAsync("bsqliteDemo.download", "app.db", image);Seed a tab from a file
Replaces the named database on the selected backend and records the sticky binding, so the next open finds the imported data instead of creating an empty file elsewhere. The worker is closed first: an open connection would keep writing the image being replaced.
// Close the worker first so it cannot keep writing the image being replaced.
await Database.CloseSessionAsync();
await provider.Admin.ImportAsync("app.db", bytes);
// Record the sticky binding, or the next open would create an empty file on the
// preferred backend and the import would look like it vanished.
await Database.Bindings.SetProviderNameAsync("app.db", provider.Name);
// Reopen once so migrations run before the pages come back for the database. The
// open raises Opened, which is how every page hears it should reload.
await using (await Database.OpenContextAsync())
{
}Start over
Removes app.db from the current backend and
forgets the binding, so the next open is free to pick the preferred provider again,
run the migrations, and reseed.
await Database.CloseSessionAsync();
await provider.Admin.DeleteAsync("app.db");
// Forget the binding so selection is free to pick the preferred backend again.
await Database.Bindings.RemoveAsync("app.db");
// Migrates and reseeds the now-empty database.
await using (await Database.OpenContextAsync())
{
}