EF Core 9.0 (EF 9) introduced new methods UseSeeding and UseAsyncSeeding to seed the initial data.
Let's have a look at an example.
Consider the following MyDbContext.
public record Blog
{
public int Id { get; set; }
public string Name { get; set; }
}
public class MyDbContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder
.UseSqlServer("<ConnectionString>");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>(x =>
{
x.HasData
(
new Blog
{
Id = 1,
Name = "Some Blog"
}
);
});
}
}
Here in the above example, some data is seeded through Model-managed data which is handly when we want to include seed data in migrations as well and it was available for as far as I can remember.
Now let's see where UseSeeding and UseAsyncSeeding come in.
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder
.UseSqlServer("<ConnectionString>")
.UseSeeding((context, _) =>
{
Blog? blog = context.Set<Blog>().SingleOrDefault(b => b.Name == "Some Other Blog");
if (blog is null)
{
context.Set<Blog>().Add(new Blog { Name = "Some Other Blog" });
context.SaveChanges();
}
})
.UseAsyncSeeding(async (context, _, cancellationToken) =>
{
Blog? blog = await context.Set<Blog>().SingleOrDefaultAsync(b => b.Name == "Some Other Blog", cancellationToken);
if (blog is null)
{
context.Set<Blog>().Add(new Blog { Name = "Some Other Blog" });
await context.SaveChangesAsync(cancellationToken);
}
});
}
As you can see, the new seeding methods are available as part of configuring DbContextOptions. Unlike Model-managed data, you can seed data for multiple DbSets all from a single place. These methods will get called as part of EnsureCreated operation, Migrate and dotnet ef database update command, even if there are no model changes and no migrations were applied.
Now let's see this in action.
using var context = new MyDbContext();
await context.Database.EnsureDeletedAsync();
await context.Database.EnsureCreatedAsync();
foreach (Blog blog in context.Blogs)
{
Console.WriteLine(blog.Name);
}
// Output:
//Some Blog
//Some Other Blog
And a note from the official documentation:
More read:
EF Core: Data Seeding
Happy Coding.
Regards,
Jaliya