--- title: "CLI Scaffolding" description: "Generate entities, DAOs, databases, and migrations with the RoomSharp CLI." canonical: "https://roomsharp.dev/docs/v0.5.4/cli-scaffolding" source: "src/content/v0.5.4/cli-scaffolding.mdx" --- # Scaffolding Commands All scaffolding commands accept scoped names with `/` or `\` to create nested folders under the configured path (including the derived namespace). For example: ```bash room make:dao Api/V1/User # => Data/Daos/Api/V1/IUserDao.cs (or under --path if provided) ``` ## make:entity Creates a new entity class representing a database table. ```bash room make:entity User --table=users ``` **Generated Output:** ```csharp 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 Creates a new Data Access Object interface. ```bash make:dao [--entity=Name] [--path=Data/Daos] [--table=...] [--entity-ns=...] [--ns=...] [--force] [--dry-run] ``` ```bash room make:dao User --entity=User --table=users ``` **Generated Output:** ```csharp using RoomSharp.Attributes; using MyApp.Data.Models; namespace MyApp.Data.Daos; [Dao] public interface IUserDao { [Insert] Task Insert(User entity); [Update] Task Update(User entity); [Delete] Task Delete(User entity); [Query("SELECT * FROM users ORDER BY Id", NoTracking = true)] Task> GetAllAsync(); } ``` ## make:database Creates the abstract database class that combines all your DAOs. ```bash room make:database AppDatabase --version=1 --entities=User ``` The generated code uses collection expressions which require C# 12. **Generated Output:** ```csharp 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 Creates a manual migration class for custom schema changes. ```bash room make:migration Migration_1_2 --from=1 --to=2 ``` **Generated Output:** ```csharp 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 Creates an auto-migration spec for declarative schema changes. ```bash room make:auto-migration AutoSpec_1_2 ``` **Generated Output:** ```csharp 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 are declared directly on the `RoomDatabase` class using the `[AutoMigration]` attribute. They can be executed either at runtime (when the app starts) or via CLI (`room migrate:up`). Both share the same migration engine. ## make:seeder Creates a seeder class for populating test/seed data. ```bash room make:seeder User --entity=User --order=10 ``` **Options:** | Option | Description | |--------|-------------| | `--entity=User` | Link to entity type (adds `EntityType` to attribute) | | `--order=10` | Execution order (default: 10) | | `--path=...` | Override output path | | `--ns=...` | Override namespace | **Generated Output:** ```csharp 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; } } ``` ## make:repository Creates a repository pattern implementation for an entity. Useful for projects that prefer the repository pattern over direct DAO usage. ```bash room make:repository [options] ``` **Options:** | Option | Description | |--------|-------------| | `--path=...` | Override output path (default: `Data/Repositories`) | | `--ns=...` | Override namespace | | `--force` | Overwrite existing file | | `--dry-run` | Preview without writing | **Examples:** ```bash # Basic usage room make:repository User # With custom path and namespace room make:repository User --path=Data/Repositories --ns=MyApp.Data.Repositories # Scoped/nested path room make:repository Api/V1/User # => Data/Repositories/Api/V1/UserRepository.cs ``` **Generated Output:** ```csharp using MyApp.Data.Daos; using MyApp.Data.Models; namespace MyApp.Data.Repositories; public interface IUserRepository { Task GetByIdAsync(long id); Task> GetAllAsync(); Task CreateAsync(User entity); Task UpdateAsync(User entity); Task DeleteAsync(User entity); } public sealed class UserRepository : IUserRepository { private readonly IUserDao _dao; public UserRepository(IUserDao dao) { _dao = dao; } public Task GetByIdAsync(long id) => _dao.GetByIdAsync(id); public Task> GetAllAsync() => _dao.GetAllAsync(); public Task CreateAsync(User entity) => _dao.Insert(entity); public Task UpdateAsync(User entity) => _dao.Update(entity); public Task DeleteAsync(User entity) => _dao.Delete(entity); } ``` The repository pattern provides an abstraction layer over DAOs, making it easier to swap implementations or add cross-cutting concerns like caching or logging. ## make:config Generates a `room.config.json` file with default settings. ```bash room make:config --provider sqlite --connection "Data Source=room.db" --ns MyApp.Data ``` **Options:** | Option | Description | |--------|-------------| | `--provider=...` | Database provider (`sqlite`, `pgsql`, `mysql`, `sqlserver`) | | `--connection=...` | Connection string | | `--ns=...` | Namespace root | | `--force` | Overwrite existing config | | `--dry-run` | Preview without writing | **Generated Output:** ```json { "provider": "sqlite", "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" } ``` ## make:view Creates a DatabaseView entity for mapping SQL views. ```bash room make:view [--view=view_name] [--query="SELECT ..."] [--path=...] [--ns=...] [--force] [--dry-run] ``` **Examples:** ```bash room make:view UserStats --view=user_stats room make:view UserStats --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:** ```csharp using RoomSharp.Attributes; namespace MyApp.Data.Views; /// /// Database view mapped to the 'user_stats' view. /// [DatabaseView(ViewName = "user_stats", Query = "SELECT * FROM your_table")] public sealed record UserStatsView { // Map columns from your view query here public long Id { get; set; } // TODO: Add properties matching your view columns } ``` ## make:converter Creates a TypeConverter class for custom type mappings. ```bash room make:converter [--from=Type] [--to=Type] [--path=...] [--ns=...] [--force] [--dry-run] ``` **Examples:** ```bash room make:converter JsonConverter --from=MyModel --to=string room make:converter DateOnlyConverter --from=DateOnly --to=string ``` **Generated Output:** ```csharp using RoomSharp.Converters; namespace MyApp.Data.Converters; /// /// Converts MyModel to/from string for database storage. /// public sealed class JsonConverter : TypeConverter { public override string ToProvider(MyModel value) { // Convert from your type to database type throw new NotImplementedException(); } public override MyModel ToModel(string value) { // Convert from database type to your type throw new NotImplementedException(); } } ``` TypeConverters are automatically discovered when applied to entity properties using `[TypeConverter(ConverterType = typeof(...))]`.