How can EF Core prevent seeding from being invoked multiple times in OnModelCreating()?

Viewed 57

According to documentation,

Typically OnModelCreating() is called only once when the first instance of a derived context is created. The model for that context is then cached and is for all further instances of the context in the app domain.

Now consider my code:

protected override void OnModelCreating(ModelBuilder builder)
{
    base.OnModelCreating(builder);
    builder.ApplyConfiguration(new StudentConfiguration());
}
internal class StudentConfiguration : IEntityTypeConfiguration<Student>
{
    public void Configure(EntityTypeBuilder<Student> builder)
    {
        Console.WriteLine($">>>>>>>>>>>>>>>>>>>>>> {nameof(StudentConfiguration)}");
        builder.HasData(
            new Student
            {
                Name = "Albert Einstein",
                Age = 100
            },
            new Student
            {
                Name = "Isaac Newton",
                Age = 400
            }
        );
    }
}

When invoking dotnet ef database update, the seeding is invoked. So far it is understandable.

Now if I start the application, OnModelCreating() should be invoked to create models that will be cached for all further instances of the database context in the application domain.

I see a single

>>>>>>>>>>>>>>>>>>>>>> StudentConfiguration

for the first database access in the whole life of the application. However, I don't see a duplicate seeding in the database.

Restarting the application multiple times also does not cause multiple seeding. It is actually good but how can seeding happens just once recall that Configure() is invoked multiple times, each once per application domain?

2 Answers

If you enabled your ef migrations it will create __EFMigrationsHistory table and insert your migrations to table in your database. And if your seed migration invoked it will insert to table so there can't be any rerun or duplicate your migrations.

If you wanna try to rerun the migration, delete your migration row from __EFMigrationsHistory table and update database or run your app again. But be careful if your migration change your table design it will throw error.

Table Name: Table Name

Migrations should look like this: enter image description here

HasData fluent API is part of the so called EF Core Model Data Seed. Per documentation

Unlike in EF6, in EF Core, seeding data can be associated with an entity type as part of the model configuration. Then EF Core migrations can automatically compute what insert, update or delete operations need to be applied when upgrading the database to a new version of the model.

Note

Migrations only considers model changes when determining what operation should be performed to get the seed data into the desired state. Thus any changes to the data performed outside of migrations might be lost or cause an error.

All that means that HasData calls inside OnModelCreating are used only for generating migrations (and are applied to the database only when these migrations are executed). They have no effect on runtime behavior of the db context/model/sets/CRUD operations.

Related