RoomSharp.Cli
0.5.5
dotnet tool install --global RoomSharp.Cli --version 0.5.5
dotnet new tool-manifest
dotnet tool install --local RoomSharp.Cli --version 0.5.5
#tool dotnet:?package=RoomSharp.Cli&version=0.5.5
nuke :add-package RoomSharp.Cli --version 0.5.5
RoomSharp CLI
A production-grade command-line tool for RoomSharp ORM to scaffold code, manage migrations, and export schemas with safety and validation.
Overview
RoomSharp CLI is a .NET global tool that provides:
- Scaffolding: Entities, DAOs, Database, Manual & Auto Migrations
- Runtime migrations: Apply and track schema versions
- Schema export: Dump schema for documentation and CI
- Strict validation: C#/SQL identifiers, version windows, file safety
- Multi-provider support:
- SQLite (built-in)
- PostgreSQL
- MySQL
- SQL Server
Installation
After publishing to NuGet:
dotnet tool install -g RoomSharp.Cli
Verify:
room --version
room --docs # opens CLI docs page
room --help
Quick Start
Run these commands inside an existing C# project that references RoomSharp.
dotnet tool install -g RoomSharp.Cli
# Generate config file for this project
room make:config --provider sqlite --connection "Data Source=app.db" --ns MyApp.Data
# Create new entity (entities are C# classes representing database tables)
room make:entity User --table=users
# Create new DAO (data access objects)
room make:dao User --entity=User
# Create new database class (abstract base class for RoomDatabase)
room make:database AppDatabase --version=1 --entities=User
# Apply migrations and create the database (auto-builds the project)
room migrate:up -b
Command Reference
Usage: room <command> [options]
Flags:
--version Show CLI version
--docs Open CLI docs
-i, --interactive Launch interactive mode (TUI)
-b, --build Auto-build project before running command
-r, --release Build in Release mode (use with -b)
Scaffolding Commands:
make:entity <Name> [--path=...] [--table=...] [--ns=...] [--force] [--dry-run]
make:dao <Name> [--entity=...] [--path=...] [--table=...] [--entity-ns=...] [--ns=...] [--force] [--dry-run]
make:database <Name> [--version=1] [--entities=...] [--path=...] [--ns=...] [--force] [--dry-run]
make:migration <Name> [--from=1] [--to=2] [--path=...] [--ns=...] [--force] [--dry-run]
make:auto-migration <Name> [--path=...] [--ns=...] [--force] [--dry-run]
make:seeder <Name> [--entity=...] [--order=10] [--path=...] [--ns=...] [--force] [--dry-run]
make:repository <Entity> [--path=...] [--ns=...] [--force] [--dry-run]
make:view <Name> [--view=...] [--query=...] [--path=...] [--ns=...] [--force] [--dry-run]
make:converter <Name> [--from=Type] [--to=Type] [--path=...] [--ns=...] [--force] [--dry-run]
make:config [--provider=...] [--connection=...] [--ns=...] [--force] [--dry-run]
Migration Commands: (use -b to auto-build before running)
migrate:up [--to=N] [-b] [--provider=...] [--connection=...] [--fallback-destructive]
migrate:status [-b] [--provider=...] [--connection=...]
migrate:timeline [-b] [--provider=...] [--connection=...] (visual history)
migrate:plan [--to=N] [-b] [--provider=...] [--connection=...]
migrate:verify [-b] [--provider=...] [--connection=...]
migrate:rollback [--to=N] [--steps=N] [-b] [--force] (requires IReversibleMigration)
migrate:set-version --to=N [--provider=...] [--connection=...] --force (DANGEROUS)
Database Commands: (use -b to auto-build before running)
database:drop [--provider=...] [--connection=...] [--force]
database:reset [-b] [--provider=...] [--connection=...] [--force] [--fallback-destructive]
database:seed [-b] [--env=...] [--only=A,B] [--skip=C] [--force] [--plan] [--dry-run]
[--allow-production] [--continue-on-error] [--provider=...] [--connection=...]
db:backup [--out=path] [--provider=...] [--connection=...]
db:restore --from=path [--provider=...] [--connection=...] [--force]
db:compare --target=<connection-string> [-b] [--provider=...] [--connection=...]
Inspection Commands:
info Show project and database info
doctor Run health checks on project configuration
db:tables List all tables with row counts
db:stats Show database statistics (size, rows, indexes)
generate:diagram Generate ERD (Mermaid/DBML)
db:describe <Table> Show table structure (columns, types, keys)
Schema Commands:
schema:export [--out=path] [--sql] [-b] [--provider=...] [--connection=...]
schema:validate [--schema=path] [--provider=...] [--connection=...]
Query Command:
query <SQL> [--format=table|json|csv] [--max-rows=100] [--file=path] [--allow-writes]
Global Flags:
--provider Override provider (sqlite|pgsql|mysql|sqlserver)
--connection Connection string (required for runtime commands)
--config Path to room.config.json
--force Overwrite files / skip confirmation / force re-run
--dry-run Preview without writing files or executing
Project Requirements
The CLI must be run inside a C# project that references RoomSharp. It will refuse execution otherwise.
Runtime commands (migrate:*, schema:export) require:
- A valid
RoomDatabaseimplementation - A built project (
dotnet build) - Provider + connection string via config or flags
Configuration (room.config.json)
Optional but recommended. Place at the project root.
Once configured, you no longer need to pass --provider and --connection flags with every command β the CLI reads them automatically from your config file.
{
"provider": "sqlite|pgsql|mysql|sqlserver",
"connectionString": "Data Source=room.db",
"buildConfiguration": "Debug",
"paths": {
"entities": "Data/Models",
"daos": "Data/Daos",
"database": "Data/Database",
"migrations": "Data/Migrations",
"autoMigrations": "Data/Migrations/Auto",
"schema": "Data/Schemas",
"seeders": "Data/Database/Seeders",
"views": "Data/Views",
"converters": "Data/Converters",
"repositories": "Data/Database/Repositories"
},
"namespaceRoot": "MyApp.Data"
}
π‘ Quick Generate:
room make:config --provider sqlite --connection "Data Source=room.db" --ns MyApp.Data
Connection String References
Instead of hardcoding connection strings, you can reference external sources:
From appsettings.json
{
"connectionString": "$appsettings:ConnectionStrings:DefaultConnection"
}
This reads from appsettings.json (or appsettings.{ASPNETCORE_ENVIRONMENT}.json if exists):
// appsettings.json
{
"ConnectionStrings": {
"DefaultConnection": "Data Source=app.db"
}
}
From Environment Variables
{
"connectionString": "$env:DATABASE_URL"
}
# PowerShell
$env:DATABASE_URL = "Data Source=app.db"
room migrate:status -b
# Bash
export DATABASE_URL="Data Source=app.db"
room migrate:status -b
Build Configuration
Control whether --build uses Debug or Release:
{
"buildConfiguration": "Release"
}
Or use the -r / --release flag to override:
room migrate:up -b -r # Forces Release build
SQLite Smart Path Resolution
For SQLite provider, the CLI intelligently searches for database files when only a filename is provided:
{
"provider": "sqlite",
"connectionString": "Data Source=app.db"
}
Search Order:
- Project root:
./app.db - Debug output:
bin/Debug/net*/app.db - Release output:
bin/Release/net*/app.db
If the file doesn't exist, it will be created in the project root.
Note: Full paths (absolute or explicit relative) are used as-is without searching.
Generate it fast:
room make:config --provider sqlite --connection "Data Source=room.db" --ns MyApp.Data
Global Flags
| Flag | Description |
|---|---|
--provider |
Override provider |
--connection |
Override connection string |
--config |
Path to room.config.json |
-b, --build |
Auto-build project before running command |
-r, --release |
Build in Release mode (use with -b) |
--force |
Overwrite files |
--dry-run |
Preview without writing |
--fallback-destructive |
Allow destructive fallback |
Auto-Build Flag
The -b / --build flag automatically builds your project before running commands that require a compiled assembly:
# Instead of:
dotnet build
room migrate:status
# Just use:
room migrate:status -b
Output:
β Building project (Debug)... (2.1s)
β Build succeeded (3.2s)
Current version : 1
Target version : 3
Pending migrations:
β’ Migration_1_2 (1 β 2)
β’ Migration_2_3 (2 β 3)
Build Configuration
By default, -b builds in Debug mode. To build in Release:
# Method 1: CLI flag
room migrate:up -b -r
room migrate:up -b --release
# Method 2: room.config.json
{
"buildConfiguration": "Release"
}
Priority: CLI flag
-rtakes precedence overbuildConfigurationin config.
Scaffolding Commands
All scaffolding commands accept scoped names with / or \ to create nested folders under the configured path (including the derived namespace). For example:
room make:dao Api/V1/User
# => Data/Daos/Api/V1/IUserDao.cs (or under --path if provided)
Scaffolding commands normalize common RoomSharp naming conventions before writing files. The generated file and type use the normalized name, and the CLI prints Normalized name: ... when it changes the input.
| Command | Accepted input | Generated type/file |
|---|---|---|
make:dao |
User, UserDao, IUserDao |
IUserDao |
make:database |
App, AppDatabase |
AppDatabase |
make:seeder |
User, UserSeeder |
UserSeeder |
make:repository |
User, UserRepository, IUserRepository |
IUserRepository and UserRepository |
make:view |
UserStats, UserStatsView |
UserStatsView |
make:converter |
DateOnly, DateOnlyConverter |
DateOnlyConverter |
make:entity
room make:entity User --table=users
Generated Output (Exact):
using RoomSharp.Attributes;
namespace MyApp.Data.Models;
[Entity(TableName = "users")]
public sealed record User
{
[PrimaryKey(AutoGenerate = true)]
public long Id { get; set; }
// TODO: add your columns here
}
make:dao
make:dao <Name> [--entity=Name] [--path=Data/Daos] [--table=...] [--entity-ns=...] [--ns=...] [--force] [--dry-run]
room make:dao User --entity=User --table=users
room make:dao UserDao
room make:dao IUserDao
Generated Output (Exact):
using RoomSharp.Attributes;
using MyApp.Data.Models;
namespace MyApp.Data.Daos;
[Dao]
public interface IUserDao
{
[Insert]
Task<long> Insert(User entity);
[Update]
Task<int> Update(User entity);
[Delete]
Task<int> Delete(User entity);
[Query("SELECT * FROM users ORDER BY Id", NoTracking = true)]
Task<List<User>> GetAllAsync();
}
make:database
room make:database AppDatabase --version=1 --entities=User
β οΈ Requires C# 12 for collection expressions.
using Microsoft.Extensions.Logging;
using RoomSharp.Abstraction;
using RoomSharp.Attributes;
using RoomSharp.Core;
using MyApp.Data.Models;
using MyApp.Data.Daos;
namespace MyApp.Data.Database;
[Database(Version = 1, Entities = [typeof(User)])]
public abstract class AppDatabase(
IDatabaseProvider provider,
ILogger logger
) : RoomDatabase(provider, logger)
{
public abstract IUserDao UserDao { get; }
}
make:migration
room make:migration Migration_1_2 --from=1 --to=2
using System.Threading;
using System.Threading.Tasks;
using RoomSharp.Migrations;
namespace MyApp.Data.Migrations;
public sealed class Migration_1_2 : IRoomMigration
{
public int StartVersion => 1;
public int EndVersion => 2;
public string Id => "MyApp.Data.Migrations.Migration_1_2:1->2";
public string Name => "Migration_1_2";
private const string Body = """
-- TODO: describe the migration deterministically (SQL text, notes, etc.)
""";
public string Checksum => MigrationChecksum.Sha256(Body);
public async Task UpAsync(MigrationContext ctx)
{
await using var cmd = ctx.CreateCommand("""
-- TODO: add your DDL/DML here
""");
await cmd.ExecuteNonQueryAsync(ctx.CancellationToken);
}
}
make:auto-migration
room make:auto-migration AutoSpec_1_2
using System.Data.Common;
using RoomSharp.Migrations.Auto;
namespace MyApp.Data.Migrations.Auto;
[RenameTable(FromTableName = "old_table", ToTableName = "new_table")]
[AddColumn(TableName = "your_table", ColumnName = "new_column", ColumnDefinition = "INTEGER NOT NULL DEFAULT 0")]
[DeleteColumn(TableName = "your_table", ColumnName = "obsolete_column")]
[DeleteTable(TableName = "legacy_table")]
public sealed class AutoSpec_1_2 : IAutoMigrationSpec
{
public void OnPostMigrate(DbConnection connection)
{
// Optional: data fixups after DDL
}
}
Auto Migrations: Runtime vs CLI
Auto migrations are declared directly on the RoomDatabase class using the
[AutoMigration] attribute.
They can be executed in two ways:
- At runtime: when the application starts and initializes the database.
- Via CLI: using
room migrate:up, which loads the same compiled assembly and executes the same migration pipeline.
There is no separate migration logic for the CLI. The CLI and runtime share the exact same migration engine.
make:config
room make:config --provider sqlite --connection "Data Source=room.db" --ns MyApp.Data
Generates room.config.json using the current defaults or provided overrides.
make:seeder
room make:seeder <Name> [options]
Generates a seeder class implementing IRoomSeeder.
Options
| Option | Description |
|---|---|
--entity=User |
Link to entity type (adds EntityType to attribute) |
--order=10 |
Execution order (default: 10) |
--path=... |
Override output path (default: paths.seeders from config) |
--ns=... |
Override namespace |
Examples
room make:seeder User --entity=User --order=10
# => Data/Database/Seeders/UserSeeder.cs
room make:seeder Api/V1/AdminSeeder --entity=User
# => Data/Database/Seeders/Api/V1/AdminSeeder.cs
room make:seeder TestData --path=Tests/Seeders
# => Tests/Seeders/TestDataSeeder.cs
Generated Code
using RoomSharp.Attributes;
using RoomSharp.Seeding;
namespace MyApp.Data.Database.Seeders;
[Seeder(EntityType = typeof(User), Order = 10, RunInTransaction = true, Repeatable = false)]
public sealed class UserSeeder : IRoomSeeder
{
public string? SeedVersion => "1.0.0";
public async ValueTask SeedAsync(SeederContext ctx)
{
// Idempotent seeding logic here
ctx.LogMessage("UserSeeder executed successfully");
await Task.CompletedTask;
}
}
Runtime Migration Commands
β οΈ IMPORTANT: Runtime commands load your compiled assembly. If you modify code (entities, migrations, database), you MUST rebuild before running these commands to avoid unexpected behavior.
Build Requirements
Option 1: Manual Build
dotnet build
room migrate:status
Option 2: Auto-Build (Recommended)
room migrate:status -b # Debug build
room migrate:status -b -r # Release build
Runtime commands that require a built assembly:
migrate:up,migrate:status,migrate:plan,migrate:verifydatabase:reset,database:seedschema:export,schema:validate
Runtime commands require both provider and connectionString (either from room.config.json or via flags).
migrate:status
room migrate:status
Sample output:
Current version : 0
Target version : 3
Latest migration: 3
Pending migrations:
- Migration_1_2 (1->2)
- Migration_2_3 (2->3)
migrate:up
room migrate:up --to=3
- Applies auto + manual migrations
- Uses
MigrationManagerunder the hood - Optionally allows destructive fallback with
--fallback-destructive - Rebuilds schema via
SchemaGeneratorafter migrations
migrate:plan
Prints the exact migration chain that would be applied (strict pathing: no gaps, no branching).
room migrate:plan --to=3
migrate:verify
Verifies applied migrations against their recorded checksums in __room_migrations.
room migrate:verify
migrate:set-version (DANGEROUS)
This does not roll back schema changes. It only edits __room_state for manual recovery scenarios.
room migrate:set-version --to=2 --force
Use only if you know exactly what youβre doing (prefer restoring from a backup in production).
Schema Export
room schema:export --out ./schema_export
- Uses
SchemaMigrationExporterto export schema for the active provider and version. - Includes
[DatabaseView(Managed = true)]definitions in JSON and SQL exports. - Defaults to
schema_exportfolder at project root if--outis not provided (or to thepaths.schemavalue fromroom.config.jsonif present).
Raw SQL Export
room schema:export --sql --out ./schema_sql
Use --sql to export raw CREATE TABLE DDL statements instead of JSON. Useful for:
- DBA reviews
- CI/CD verification
- Database documentation
Schema Validate
room schema:validate --provider=sqlserver --connection="..." --schema=./schema_export
- Uses
SchemaRuntimeValidator.EnsureSchemato validate the live database schema against exported files. - Validates managed database views from the compiled project, so missing or changed managed views are detected.
- Defaults to
schema_exportfolder at project root if--schemais not provided (or to thepaths.schemavalue fromroom.config.jsonif present).
Inspection Commands
Commands for inspecting project configuration and database state.
info
Display project and database information:
room info
Sample Output:
β RoomSharp Project Info
β
β Project
β Name MyApp.csproj
β Root C:\path\to\project
β Provider sqlite
β Connection β configured
β Namespace MyApp
β
β Paths
β Entities Data/Models
β DAOs Data/Daos
β Database Data/Database
β Migrations Data/Migrations
β Seeders Data/Database/Seeders
β
β Database
β Class AppDatabaseImpl
β Schema Version 2
β Entities 3
β Current Version 2
β Migrations 1 total, 0 pending
β Tables 5
β
β β Info retrieved
doctor
Run health checks on project configuration:
room doctor
Sample Output:
β RoomSharp Doctor
β β’ room.config.json found
β β’ Provider: sqlite
β β’ Connection string configured
β β’ RoomDatabase found: AppDatabaseImpl
β Entities: 3
β Version: 2
β β’ Database connection successful
β β’ Migrations up to date
β
β β All checks passed
db:tables
List all tables in the database with row counts:
room db:tables
Sample Output:
β Found 3 table(s) (90ms)
β Database Tables
β Table Rows
β βββββββββββββββββββββββββββββ
β __room_migrations 1
β __room_state 1
β users 150
β
β 3 table(s)
db:describe
Show table structure with columns, types, and keys:
room db:describe <TableName>
room db:describe users
Sample Output:
β Found 3 column(s) (91ms)
β Table: users
β Column Type Null Key Default
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Id INTEGER YES PK NULL
β Name TEXT YES NULL
β Email TEXT NO NULL
β
β 3 column(s)
db:stats
Display database statistics including size, table counts, and index information:
room db:stats
Sample Output:
β Statistics gathered (91ms)
β Database Statistics
Provider: SQLite
Size: 36.0 KB
Tables: 4
Total Rows: 3
Indexes: 3
Table β Rows β Cols β Idx
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
__room_migrations β 1 β 9 β 1
__room_state β 1 β 7 β 0
notes β 1 β 4 β 1
β 4 table(s), 3 row(s)
generate:diagram
Generate an Entity-Relationship Diagram (ERD) in Mermaid or DBML format:
room generate:diagram [options]
| Option | Description |
|---|---|
--output=path |
Save to file (prints to console if omitted) |
--format=mermaid\|dbml |
Output format (default: mermaid) |
Examples:
# Print Mermaid diagram to console
room generate:diagram
# Save DBML to file
room generate:diagram --output=schema.dbml --format=dbml
# Save Mermaid to file
room generate:diagram --output=docs/erd.md --format=mermaid
migrate:rollback
Rolls back migrations using the IReversibleMigration interface:
room migrate:rollback # Roll back 1 step
room migrate:rollback --steps=3 # Roll back 3 steps
room migrate:rollback --to=5 # Roll back to version 5
room migrate:rollback --force # Skip confirmation
| Option | Description |
|---|---|
--to=N |
Roll back to specific version |
--steps=N |
Roll back N steps (default: 1) |
--force |
Skip confirmation prompt |
-b |
Auto-build before running |
β οΈ Requires IReversibleMigration: Only migrations implementing
IReversibleMigrationwithDownAsynccan be rolled back.
migrate:timeline
Displays a visual timeline of applied migrations:
room migrate:timeline
Sample Output:
β Migration Timeline
Date β Migration β Time β Status
ββββββββββββββββββΌβββββββββββββββββββββββββββββββββββΌβββββββββββΌβββββββ
2024-12-15 10:30 β Migration_1_2 β 125ms β β
2024-12-18 14:15 β Migration_2_3 β 89ms β β
2024-12-20 09:00 β Migration_3_4 β 45ms β β
ββ Foreign key constraint failed...
β Current Version: 3
make:view
Creates a DatabaseView entity for mapping SQL views:
room make:view <Name> [--view=view_name] [--query="SELECT ..."] [--path=...] [--ns=...] [--force] [--dry-run]
Examples:
room make:view UserStats --view=user_stats
room make:view OrderSummary --query="SELECT u.Id, COUNT(o.Id) AS OrderCount FROM users u LEFT JOIN orders o ON u.Id = o.UserId GROUP BY u.Id"
Generated Output:
using RoomSharp.Attributes;
namespace MyApp.Data.Views;
[DatabaseView(ViewName = "user_stats", Query = "SELECT * FROM your_table")]
public sealed record UserStatsView
{
public long Id { get; set; }
// TODO: Add properties matching your view columns
}
make:converter
Creates a TypeConverter class for custom type mappings:
room make:converter <Name> [--from=Type] [--to=Type] [--path=...] [--ns=...] [--force] [--dry-run]
Examples:
room make:converter JsonConverter --from=MyModel --to=string
room make:converter DateOnlyConverter --from=DateOnly --to=string
Generated Output:
using RoomSharp.Converters;
namespace MyApp.Data.Converters;
public sealed class JsonConverter : TypeConverter<string, MyModel>
{
public override MyModel FromProvider(string provider)
{
throw new NotImplementedException();
}
public override string ToProvider(MyModel model)
{
throw new NotImplementedException();
}
}
Database Commands
β οΈ These commands require
providerandconnectionString. The CLI reads them fromroom.config.jsonwhen present, and command-line flags override config values. Build the project first for non-SQLite providers.
database:drop
room database:drop --provider=sqlite --connection="Data Source=app.db"
- SQLite: Deletes the
.db,-shm,-wal, and-journalfiles. - MySQL/PostgreSQL/SQL Server: Executes
DROP DATABASE IF EXISTS. - Prompts for confirmation unless
--forceis used.
database:reset
room database:reset --provider=sqlite --connection="Data Source=app.db" --force
Combines database:drop + migrate:up for a fresh start during development.
db:backup
room db:backup --out=backup.bak
- SQLite: Creates a consistent database copy with
VACUUM INTO. - SQL Server: Runs through the project host and creates a native
.bakbackup. - MySQL and PostgreSQL backups should use provider-native tools until first-class CLI backup support is added.
For SQL Server, the backup path is read by the SQL Server service. A relative path such as backup.bak is resolved against SQL Server's default backup directory. An absolute path must be writable by the SQL Server service account.
db:restore
room db:restore --from=backup.bak --force
- SQLite: Replaces the database file.
- SQL Server: Runs through the project host and restores the native
.bakfile.
For SQL Server, a relative path such as backup.bak is resolved against SQL Server's default backup directory. An absolute path must be readable by the SQL Server service account.
db:compare
room db:compare --target="Server=.;Database=TargetDb;Trusted_Connection=True;TrustServerCertificate=True;" -b
Compares the configured source database against a target database using the same provider. The source connection comes from room.config.json unless overridden with --connection; the target is required because it identifies the second database.
--target also supports the same connection string references as config values, including $appsettings: and $env:.
Query Command
Execute SQL queries directly from the CLI with formatted output.
Note: This command is intended for diagnostics and reporting, not as a replacement for application-level data access.
room query <SQL> [options]
room query --file=queries/report.sql [options]
Options
| Option | Description |
|---|---|
--format=table |
Output format: table (default), json, csv |
--max-rows=100 |
Limit returned rows (default: 100) |
--file=path |
Execute SQL from a file |
--allow-writes |
Enable INSERT/UPDATE/DELETE/DROP operations |
Examples
# Simple query
room query "SELECT * FROM users LIMIT 10"
# With JSON output
room query "SELECT id, name FROM users" --format=json
# Export to CSV
room query "SELECT * FROM orders" --format=csv > orders.csv
# Execute from file
room query --file=reports/monthly.sql --max-rows=500
# Write operations (requires --allow-writes)
room query "UPDATE users SET active = 1 WHERE id = 5" --allow-writes
Output Formats
Table (default):
+----+-----------+-------------------+--------+
| Id | Name | Email | Active |
+----+-----------+-------------------+--------+
| 1 | Ahmed | ahmed@example.com | true |
| 2 | Sara | sara@example.com | false |
+----+-----------+-------------------+--------+
JSON:
[
{"Id": 1, "Name": "Ahmed", "Email": "ahmed@example.com", "Active": true},
{"Id": 2, "Name": "Sara", "Email": "sara@example.com", "Active": false}
]
CSV:
"Id","Name","Email","Active"
1,"Ahmed","ahmed@example.com","True"
2,"Sara","sara@example.com","False"
β οΈ Safety: Write operations (
INSERT,UPDATE,DELETE,DROP, etc.) are blocked by default. Use--allow-writesto enable them.
database:seed
Advanced seeding with idempotency, dependency ordering, and production safety.
room database:seed [options]
Flags
| Flag | Description |
|---|---|
--env=Development |
Environment filter (default: ASPNETCORE_ENVIRONMENT or Development) |
--only=A,B |
Run only specified seeders |
--skip=A,B |
Skip specified seeders |
--force |
Force re-run even if already applied |
--plan |
Show execution plan without running |
--dry-run |
Preview mode - no actual execution |
--allow-production |
Allow running in Production environment |
--continue-on-error |
Continue running other seeders if one fails |
Example
room database:seed --env=Development --plan
room database:seed --only=UserSeeder,RoleSeeder --force
room database:seed --skip=TestDataSeeder
Implementing a Seeder
using RoomSharp.Attributes;
using RoomSharp.Seeding;
[Seeder(EntityType = typeof(User), Order = 10, DependsOn = new[] { typeof(RoleSeeder) })]
public sealed class UserSeeder : IRoomSeeder
{
public string? SeedVersion => "1.0.0"; // Change to trigger re-run
public async ValueTask SeedAsync(SeederContext ctx)
{
var dao = ((AppDatabase)ctx.Database).UserDao;
// Idempotent: check before insert
if (!await dao.ExistsByEmailAsync("admin@local"))
{
await dao.InsertAsync(new User { Email = "admin@local", Role = "Admin" });
}
ctx.LogMessage("UserSeeder completed");
}
}
Seeder Attribute Options
| Property | Description |
|---|---|
EntityType |
Entity type this seeder populates (for documentation) |
Order |
Execution order within same dependency level |
DependsOn |
Seeder types that must run first |
Environments |
Allowed environments (empty = all) |
RunInTransaction |
Wrap in transaction (default: true) |
Repeatable |
Can re-run based on SeedVersion hash (default: false) |
Seeder Journal
The CLI tracks applied seeders in __room_seed_journal table:
| Column | Description |
|---|---|
SeederId |
Full type name |
Version |
SeedVersion value |
AppliedAt |
Timestamp |
Environment |
Environment name |
AssemblyName |
Source assembly |
Interactive Mode
Launch a menu-driven interface with the --interactive (or -i) flag:
room --interactive
room -i
The TUI guides you through:
- Creating entities, DAOs, databases, migrations, and seeders
- Running migrations
- Seeding the database
- Exporting schemas
- Resetting the database
Providers
| Provider | Value | Package |
|---|---|---|
| SQLite | sqlite |
Built-in in RoomSharp |
| PostgreSQL | pgsql |
RoomSharp.PostgreSql |
| MySQL | mysql |
RoomSharp.MySql |
| SQL Server | sqlserver |
RoomSharp.SqlServer |
For non-SQLite providers, make sure you reference the corresponding RoomSharp provider package.
Safety & Validation
RoomSharp CLI is designed to be safe-by-default:
- Refuses to run outside a RoomSharp-enabled C# project.
- Validates:
- C# identifiers for generated types and namespaces.
- SQL identifiers for table names.
- Migration version windows (
to > from).
- Prevents overwriting files unless
--forceis explicitly used. --dry-runalways shows intended writes without touching the filesystem.- Runtime commands will fail fast if:
- Provider is missing (
--provideror config). - Connection string is missing (
--connectionor config). - No
RoomDatabaseimplementation is found in the built assembly.
- Provider is missing (
Important Runtime Notes
The CLI loads your application assembly via reflection:
- It searches for the
.csprojclosest to the working directory. - It determines the assembly name from
<AssemblyName>or the project file name. - It looks under
bin/Debug|Release/net*for the built DLL. - It then finds the first concrete type assignable to
RoomDatabase.
If it cannot find the assembly or database type, it will emit:
Could not locate built assembly. Please run 'dotnet build' first (Debug or Release).
No RoomDatabase implementation found in assembly.
Always ensure:
dotnet build
runs successfully before migrate:* or schema:export.
π‘ Tip: Use
-bflag to auto-build:room migrate:status -b
License
This project is licensed under the MIT License - see the LICENSE file for details.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
This package has no dependencies.
RoomSharp.Cli v0.5.3
This release aligns RoomSharp.Cli with the RoomSharp v0.5.3 ecosystem.
Starting with v0.5.3, RoomSharp uses synchronized versioning across ecosystem packages. Packages released as part of the same ecosystem update now share the same version number.
RoomSharp.Cli previously followed an independent version line. Its last independent release was v0.1.8. The version jump to v0.5.3 is intentional and reflects ecosystem alignment, not a breaking change by itself.
CLI highlights since v0.1.8:
- Added database backup support via db:backup.
- Added database restore support via db:restore.
- Added schema comparison support via db:compare.
- Added migration rollback support via migrate:rollback.
- Added migration timeline visualization via migrate:timeline.
- Added database statistics via db:stats.
- Added ERD generation via generate:diagram.
- Added scaffolding for DatabaseView entities via make:view.
- Added scaffolding for TypeConverter classes via make:converter.
- Added views, converters, and repositories paths to room.config.json.
- Fixed MySQL transaction handling in rollback operations.
- Added user-friendly version mismatch detection with actionable solutions.
- Updated dependencies.
See the changelog for full details.