100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
C#

Seeding Data

Techniques for populating a database with initial or reference data using EF Core, from model-based HasData to imperative startup seeding.

MigrationsIntermediate9 min readJul 10, 2026
Analogies

Model-Based Seeding with HasData

HasData(), called inside OnModelCreating on an entity type builder, lets you declare static seed rows as part of the model itself. EF Core treats this data as part of the model, meaning any change to seed values generates a migration with explicit InsertData, UpdateData, or DeleteData operations the next time you run migrations add. This makes seed data versioned and reproducible across every environment, but it requires you to specify primary key values explicitly since EF Core cannot resolve identity or generated values at model-build time.

🏏

Cricket analogy: It's like a tournament's official rulebook printing the fixed opening-day squad list in advance — any roster change later must be issued as a formal amendment, not a quiet edit to the original list.

csharp
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Role>().HasData(
        new Role { Id = 1, Name = "Admin" },
        new Role { Id = 2, Name = "Member" },
        new Role { Id = 3, Name = "Viewer" }
    );
}

Imperative Seeding at Startup

For data that depends on runtime conditions, configuration values, or external calls, imperative seeding — calling a static SeedAsync method after context.Database.Migrate() in Program.cs — checks a condition such as if (!await context.Products.AnyAsync()) before inserting rows. This gives full control over conditional and dynamic logic, but the inserted data bypasses the migration history entirely, so it is not versioned, not tracked in __EFMigrationsHistory, and not automatically reversible the way HasData rows are.

🏏

Cricket analogy: It's like a ground curator deciding on match morning whether to add extra covers based on the weather forecast — a judgment call made at runtime, not something printed in the fixed pre-season schedule.

Environment-Specific and Idempotent Seeding

Production seed data for reference or lookup tables should be idempotent and safe to re-run — typically using existence checks before AddRange(), or database-specific upsert syntax such as ON CONFLICT DO NOTHING in PostgreSQL — so rerunning a deployment never creates duplicates. Environment-specific test or demo data, on the other hand, should live in separate seed classes gated by a check like if (env.IsDevelopment()), ensuring large synthetic datasets used for local testing or demos never run against a production database.

🏏

Cricket analogy: It's like a ground crew re-marking the boundary rope before every match using fixed reference pegs, so repeating the process never shifts the boundary even if done twice by different crews.

A practical rule of thumb: use HasData for small, stable reference data that rarely changes and benefits from being versioned in migrations, such as fixed roles or status enums. Use imperative seeding for larger datasets, environment-specific demo data, or seed data that depends on runtime configuration or external services.

  • HasData() declares seed rows as part of the model, generating InsertData/UpdateData/DeleteData migration operations.
  • HasData requires explicit primary key values because EF Core cannot resolve generated identities at model-build time.
  • Imperative seeding runs custom code at startup, giving full control over conditional or dynamic seed logic.
  • Imperative seed data bypasses migration history and is not automatically versioned or reversible.
  • Production reference-data seeding should be idempotent using existence checks or database upsert syntax.
  • Environment-specific demo or test data should be gated behind environment checks to avoid running in production.
  • HasData suits small, stable reference data; imperative seeding suits large or environment-dependent datasets.

Practice what you learned

Was this page helpful?

Topics covered

#EntityFrameworkCoreStudyNotes#MicrosoftTechnologies#SeedingData#Seeding#Data#Model#Based#StudyNotes#SkillVeris#ExamPrep