Mastering UseSeeding and UseAsyncSeeding in EF Core 9

What Are UseSeeding and UseAsyncSeeding Methods in EF Core 9?

In Entity Framework Core (EF Core) 9, UseSeeding and UseAsyncSeeding are methods introduced to simplify and optimize the process of data seeding in a database. Data seeding refers to pre-populating a database with essential or default data when initializing or updating a database schema.

  • UseSeeding is a synchronous method for adding initial data to a database.
  • UseAsyncSeeding is its asynchronous counterpart, designed to handle seeding operations where asynchronous calls are required, such as external API data retrieval or long-running operations.

These methods provide one clear location where all the data seeding codes can be placed.

Why Are These Methods Important?

  1. Streamlined Data Initialization: They provide a standardized approach to populate essential data into the database during migrations or application startup.
  2. Improved Asynchronous Handling: UseAsyncSeeding is particularly valuable for large-scale or remote data operations that require asynchronous execution, improving performance and responsiveness.
  3. Enhanced Maintainability: These methods make it easier to separate seeding logic from the application code, improving modularity and readability.

When Should You Use Them?

  • UseSeeding is ideal when:
    • You need to seed small, predefined datasets like default roles, configurations, or application settings.
    • The seeding process is straightforward and does not involve external data sources.
  • UseAsyncSeeding is suitable when:
    • You’re working with large datasets.
    • The seeding process involves asynchronous operations like fetching data from external APIs, files, or other services.
    • There are performance constraints that require non-blocking operations.

Where to Use These Methods?

These methods are typically used in the following scenarios:

  • During application startup, ensure the database is pre-populated with critical data.
  • In migration scripts, add new datasets as part of schema evolution.
  • In testing environments, populate mock data for integration or end-to-end tests.

How to Use UseSeeding and UseAsyncSeeding in EF Core 9?

Example 1. Using UseSeeding

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

public static IHost SeedData(this IHost host)
{
    using (var scope = host.Services.CreateScope())
    {
        var context = scope.ServiceProvider.GetRequiredService<MyDbContext>();
        context.Database.Migrate();
    }
    return host;
}

In the Program.cs file:

var app = builder.Build();
app.SeedData();

Example 2. Using UseAsyncSeeding (Asynchronous)

For larger datasets or async workflows:

public static async Task<IHost> SeedDataAsync(this IHost host)
{
    using (var scope = host.Services.CreateScope())
    {
        var context = scope.ServiceProvider.GetRequiredService<MyDbContext>();
        await context.Database.MigrateAsync();

        if (!await context.Roles.AnyAsync())
        {
            await context.Roles.AddRangeAsync(
                new Role { Id = 1, Name = "Admin" },
                new Role { Id = 2, Name = "User" }
            );
            await context.SaveChangesAsync();
        }
    }
    return host;
}

In the Program.cs file:

await app.SeedDataAsync();

Note. The ๐—จ๐˜€๐—ฒ๐—ฆ๐—ฒ๐—ฒ๐—ฑ๐—ถ๐—ป๐—ด and ๐—จ๐˜€๐—ฒ๐—”๐˜€๐˜†๐—ป๐—ฐ๐—ฆ๐—ฒ๐—ฒ๐—ฑ๐—ถ๐—ป๐—ด methods are invoked as part of the ๐™€๐™ฃ๐™จ๐™ช๐™ง๐™š๐˜พ๐™ง๐™š๐™–๐™ฉ๐™š๐™™ operation, the ๐™ˆ๐™ž๐™œ๐™ง๐™–๐™ฉ๐™š method, and the ๐™™๐™ค๐™ฉ๐™ฃ๐™š๐™ฉ ๐™š๐™› ๐™™๐™–๐™ฉ๐™–๐™—๐™–๐™จ๐™š ๐™ช๐™ฅ๐™™๐™–๐™ฉ๐™š command, even when no model changes or migrations are applied.

๐—จ๐˜€๐—ฒ๐—ฆ๐—ฒ๐—ฒ๐—ฑ๐—ถ๐—ป๐—ด is invoked by the ๐™€๐™ฃ๐™จ๐™ช๐™ง๐™š๐˜พ๐™ง๐™š๐™–๐™ฉ๐™š๐™™ method, while ๐—จ๐˜€๐—ฒ๐—”๐˜€๐˜†๐—ป๐—ฐ๐—ฆ๐—ฒ๐—ฒ๐—ฑ๐—ถ๐—ป๐—ด is invoked by the ๐™€๐™ฃ๐™จ๐™ช๐™ง๐™š๐˜พ๐™ง๐™š๐™–๐™ฉ๐™š๐™™๐˜ผ๐™จ๐™ฎ๐™ฃ๐™˜ method. When utilizing this feature, it’s recommended to implement both ๐—จ๐˜€๐—ฒ๐—ฆ๐—ฒ๐—ฒ๐—ฑ๐—ถ๐—ป๐—ด and ๐—จ๐˜€๐—ฒ๐—”๐˜€๐˜†๐—ป๐—ฐ๐—ฆ๐—ฒ๐—ฒ๐—ฑ๐—ถ๐—ป๐—ด with similar logic, even if your application primarily uses asynchronous code. This is because ๐—˜๐—™ ๐—–๐—ผ๐—ฟ๐—ฒ tooling currently depends on the synchronous ๐—จ๐˜€๐—ฒ๐—ฆ๐—ฒ๐—ฒ๐—ฑ๐—ถ๐—ป๐—ด method, and the database seeding process will not function correctly if it is not implemented.


Similar Articles