liveBook · Manning

Data seeding

As explained in Pro ASP.NET Core 7, Tenth Edition

Seed data is initial data inserted into an application's database to establish required records and state.

Data seeding inserts initial records so an application has something to work with on a new database. Run it after applying pending Entity Framework Core migrations, then check whether the relevant tables are empty before adding objects and calling SaveChanges. That check prevents another copy of the sample data appearing on every startup. section 7.2.7 section 18.2.3

Choose when and what to seed:

  • For application data, resolve the DbContext from an application service scope and invoke the seeding method from Program.cs before app.Run(). Related records can include suppliers, categories, and products; Entity Framework Core maps them to tables and assigns database-generated keys. section 7.2.7 section 18.2.3
  • For development data, seed automatically in the Development environment. An INITDB=true configuration setting can instead trigger a one-off run that exits without starting the HTTP listener—useful for staging or production testing. section 17.5.5
  • For ASP.NET Core Identity, seed an administrator account and role before role-restricted administration tools become inaccessible. Resolve the scoped UserManager and RoleManager services in a new scope; change any default password after deployment or keep sensitive values outside project files. section 39.3.4 section 11.1.6
Listing 7.22 The contents of the SeedData.cs file in the SportsStore/Models folder
using Microsoft.EntityFrameworkCore;

namespace SportsStore.Models {

   public static class SeedData {
       
       public static void EnsurePopulated(IApplicationBuilder app) {
           StoreDbContext context = app.ApplicationServices
               .CreateScope().ServiceProvider
               .GetRequiredService<StoreDbContext>();
                               
           if (context.Database.GetPendingMigrations().Any()) {
               context.Database.Migrate();
           }
                       
           if (!context.Products.Any()) {
               context.Products.AddRange(
                   new Product {
                       Name = "Kayak", Description = 
                           "A boat for one person",
                       Category = "Watersports", Price = 275
                   },
                   new Product {
                       Name = "Lifejacket",
                       Description = "Protective and fashionable",
                       Category = "Watersports", Price = 48.95m
                   },
                   new Product {
                       Name = "Soccer Ball",
                       Description = "FIFA-approved size and weight",
                       Category = "Soccer", Price = 19.50m
                   },
                   new Product {
                       Name = "Corner Flags",
                       Description = 
                         "Give your playing field a professional touch",
                       Category = "Soccer", Price = 34.95m
                   },
                   new Product {
                       Name = "Stadium",
                       Description = "Flat-packed 35,000-seat stadium",
                       Category = "Soccer", Price = 79500
                   },
                   new Product {
                       Name = "Thinking Cap",
                       Description = "Improve brain efficiency by 75%",
                       Category = "Chess", Price = 16
                   },
                   new Product {
                       Name = "Unsteady Chair",
                       Description = 
                         "Secretly give your opponent a disadvantage",
                       Category = "Chess", Price = 29.95m
                   },
                   new Product {
                       Name = "Human Chess Board",
                       Description = "A fun game for the family",
                       Category = "Chess", Price = 75
                   },
                   new Product {
                       Name = "Bling-Bling King",
                       Description = "Gold-plated, diamond-studded King",
                       Category = "Chess", Price = 1200
                   }
               );
               context.SaveChanges();
           }
       }
   }
}

The SeedData.cs listing shows the startup pattern in one place: obtain StoreDbContext, apply pending migrations, test for products, add the initial objects, and save. section 7.2.7

Run a one-off seed

From the project folder, run `dotnet run INITDB=true`. The configured startup path seeds ten calculation results and terminates rather than listening for requests. To reset the SportsStore product database, run `dotnet ef database drop --force --context StoreDbContext`, then restart the application to recreate and seed it. section 17.5.5 section 7.2.7

Using ordinary Entity Framework Core inserts is more flexible than its built-in seeding feature when the database must allocate unique keys. Keep the empty-database check aligned with the records being inserted: an example with products, suppliers, and categories checks all three sets. section 17.5.5 section 18.2.3

How Pro ASP.NET Core 7, Tenth Edition covers it

How deep it goes
Works through migrations, service scopes, empty-set checks, inserts, startup calls, and explicit runs; contrasts built-in seeding with ordinary inserts.
Examples
Uses sample products, related suppliers and categories, calculation results, and an administrator account and role.
What it assumes
Assumes familiarity with ASP.NET Core service registration and Entity Framework Core contexts while showing how to connect them to startup seeding.
What you can do after
Build it from scratch with Entity Framework Core inserts and run it at startup or with INITDB=true.
How it connects
Connects Entity Framework Core migrations and DbContext to dependency injection, application configuration, and ASP.NET Core Identity.

Also explained in

Compare how 2 books explain data seeding →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Pro ASP.NET Core 7, Tenth Edition. The section links point to the parts of the book it draws on.