Seed Data Generator
Generates a DatabaseSeeder class that inserts initial rows into your database tables at application startup.
Table of contents
What It Generates
The seed data generator produces a single DatabaseSeeder.cs file containing INSERT statements for every entity that defines a seedData array in ninjadog.json. The seeder is registered in the DI container and called during application startup, immediately after the database schema is initialized.
The
DatabaseSeederfile is only generated when at least one entity includes aseedDataarray. If no entities define seed data, the file is not emitted.
Configuration
Add a seedData array to any entity in your ninjadog.json. Each element is an object whose keys match the entity’s property names.
{
"entities": {
"Category": {
"properties": {
"Id": { "type": "Guid", "isKey": true },
"Name": { "type": "string" },
"SortOrder": { "type": "int" },
"IsActive": { "type": "bool" }
},
"seedData": [
{ "Id": "550e8400-e29b-41d4-a716-446655440001", "Name": "Electronics", "SortOrder": 1, "IsActive": true },
{ "Id": "550e8400-e29b-41d4-a716-446655440002", "Name": "Books", "SortOrder": 2, "IsActive": true },
{ "Id": "550e8400-e29b-41d4-a716-446655440003", "Name": "Archive", "SortOrder": 99, "IsActive": false }
]
}
}
}
Rules
- Each seed object must include the key property (e.g.,
Id). - Boolean values are converted to
1(true) or0(false) in the generated SQL. - String values are escaped and wrapped in single quotes.
- Numeric values are inserted as literals.
- You can seed multiple entities – the seeder handles all of them in a single file.
Generated Output
Given the configuration above, Ninjadog generates:
public partial class DatabaseSeeder(IDbConnectionFactory connectionFactory)
{
public async Task SeedAsync()
{
using var connection = await connectionFactory.CreateConnectionAsync();
await connection.ExecuteAsync("INSERT INTO Categories (Id, Name, SortOrder, IsActive) VALUES ('550e8400-e29b-41d4-a716-446655440001', 'Electronics', 1, 1)");
await connection.ExecuteAsync("INSERT INTO Categories (Id, Name, SortOrder, IsActive) VALUES ('550e8400-e29b-41d4-a716-446655440002', 'Books', 2, 1)");
await connection.ExecuteAsync("INSERT INTO Categories (Id, Name, SortOrder, IsActive) VALUES ('550e8400-e29b-41d4-a716-446655440003', 'Archive', 99, 0)");
}
}
Integration with DI and Startup
The DatabaseSeeder is automatically registered in the dependency injection container and invoked at startup. In the generated Program.cs and DI extensions:
- DI Registration –
DatabaseSeederis registered as a singleton service inCrudWebApiExtensions.AddNinjadog(). - Startup Call –
DatabaseSeeder.SeedAsync()is called inCrudWebApiExtensions.UseNinjadog(), right afterDatabaseInitializer.InitializeAsync().
// In AddNinjadog()
services.AddSingleton<DatabaseSeeder>();
// In UseNinjadog()
var initializer = app.Services.GetRequiredService<DatabaseInitializer>();
await initializer.InitializeAsync();
var seeder = app.Services.GetRequiredService<DatabaseSeeder>();
await seeder.SeedAsync();
Because
DatabaseSeederis apartialclass, you can extend it with custom seeding logic in a separate file without modifying generated code.
Multiple Entities
When several entities define seed data, all INSERT statements are combined in a single DatabaseSeeder class:
{
"entities": {
"Category": {
"properties": { ... },
"seedData": [ ... ]
},
"Tag": {
"properties": {
"Id": { "type": "Guid", "isKey": true },
"Label": { "type": "string" }
},
"seedData": [
{ "Id": "660e8400-0000-0000-0000-000000000001", "Label": "Featured" },
{ "Id": "660e8400-0000-0000-0000-000000000002", "Label": "Sale" }
]
}
}
}
The generated seeder includes INSERT statements for both Categories and Tags tables.
Next Steps
- Configuration Reference – Full seed data configuration options
- Generated Examples – See the generated seeder in context
- Data Layer Generators – Database initializer and repositories
- Getting Started – End-to-end tutorial for creating your first API