Databases
The model is provider-agnostic — NetForge runs on SQLite, PostgreSQL, or SQL Server. You pick the provider at scaffold time (--database); after that it's a config switch: set Database:Provider and a matching ConnectionStrings:Default.
| Provider | Best for | Notes |
|---|---|---|
| SQLite (default) | Local dev; small / single-instance production | Zero setup, in-process. Ships EF migrations, applied on boot. Single writer — heavy concurrent writes serialize. |
| PostgreSQL | Production (recommended) | Scaffold ships a docker-compose.yml, so docker compose up -d gives you a local Postgres in one command. |
| SQL Server | Production on the Microsoft stack | Scaffold ships a docker-compose.yml. |
Migrations vs. EnsureCreated
SQLite ships a flattened InitialCreate migration and applies migrations on boot. Postgres / SQL Server scaffolds create their schema directly from the model with EnsureCreated() on first boot, so they run immediately — but without versioned migration history. The boot logic is simply: SQLite → Database.Migrate(), server providers → Database.EnsureCreated().
Why this split
The runtime supports migrations on any provider — EnsureCreated is just the chosen starting schema for server DBs, so a fresh scaffold builds and runs without shipping fragile per-provider migration sets. SQLite users get migrations from the start.
Moving a server DB to migrations
EnsureCreated is only the starting schema. When you want versioned, evolvable schema on Postgres / SQL Server, switch once — a fresh scaffold has no data, so it's clean:
- Stop the app so nothing holds the database open.
- Drop the
EnsureCreateddatabase — it has no__EFMigrationsHistorytable, so a migration can't be applied on top of it. With the bundled docker DB:docker compose down -v && docker compose up -d. - Delete the shipped
Data/Migrationsfolder — it holds the template's SQLite-shaped migration; you'll regenerate one for your provider. - Generate the initial migration:bash
dotnet ef migrations add InitialCreate --project YourApp.Server - Apply it:
dotnet ef database update --project YourApp.Server. - Auto-apply on boot (recommended): in
Program.cs, changedb.Database.EnsureCreated();todb.Database.Migrate();.
From here, every schema change is the normal dotnet ef migrations add <Name> → dotnet ef database update. Commit the Data/Migrations folder.
Dev/prod split
Scaffolding with --devSplit true (or the configurator's "Use SQLite for local dev" checkbox) puts SQLite in appsettings.Development.json while production uses the server DB. It lowers local friction, but carries a real parity risk: SQLite stores dates and money differently (NetForge applies SQLite-only value converters), and case-sensitivity, JSON querying, and concurrency all differ — so you develop and test against a different engine than you ship.
Prefer parity
Prefer the bundled docker-compose to develop against the real engine. Choose the split only if you accept testing against a different database than production.