My problem is i am trying to seed an Entity Framework Core database with data and in my mind the below code show work. I've realised that this should not be called in the ApplicationDbContext
constructor and should be called from the startup
but im not sure how to do this.
EDIT: Based on the solution provided by Ketrex, my solution is as follows:
Startup.cs:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
...
app.ApplicationServices.GetRequiredService<ApplicationDbContext>().Seed();
}
Seed extension:
public static class DbContextExtensions
{
public static void Seed(this ApplicationDbContext context)
{
// Perform database delete and create
context.Database.EnsureDeleted();
context.Database.EnsureCreated();
// Perform seed operations
AddCountries(context);
AddAreas(context);
AddGrades(context);
AddCrags(context);
AddClimbs(context);
// Save changes and release resources
context.SaveChanges();
context.Dispose();
}
private static void AddCountries(ApplicationDbContext context)
{
context.AddRange(
new Country { Name = "England", Code = "En" },
new Country { Name = "France", Code = "Fr" }
);
}
...
}
I understand that seeding a database is quite high up on the priority list for Entity Framework but it would be great if there was some documentation on how to achieve this trivial task or at least provide a temporary work around. If someone can provide some guidance on how to do this it would be greatly appreciated. I feel i'm close to a solution but just cant piece it together.
Thanks for any help.
You could also use from the Startup.cs ConfigureServices
method to make your ApplicationDbContext available (Registering the dbcontext as a service):
public void ConfigureServices(IServiceCollection services)
{
var connectionString = Startup.Configuration["connectionStrings:DBConnectionString"];//this line is not that relevant, the most important thing is registering the DbContext
services.AddDbContext<ApplicationDbContext>(o => o.UseSqlServer(connectionString));
}
and then add your ApplicationDbContext as dependency in your Configure
method which will call your seed extension method.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, ApplicationDbContext myApplicationDbContext)
{
//...
myApplicationDbContext.Seed();
}
Finally the seed method could do a quick check on an important table, because perhaps recreating the db is too heavy:
public void Seed()
{
//....
if(context.Countries.Any())
return;
//...
}
I hope it helps you or someone else, at least as another option.
Assuming you are using the built-in DI container, here is one way you can accomplish this.
Reference your seed method in the Configure method of your startup class, and pass the IApplicationBuilder object as a parameter instead of the DbContext, like this:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
//...
// Put this at the end of your configure method
DbContextSeedData.Seed(app);
}
Next, modify your seed method to accept the IApplicationBuilder instance. Then you'll be able to spin up an instance of the DbContext, and perform your seed operation, like this:
public static void Seed(IApplicationBuilder app)
{
// Get an instance of the DbContext from the DI container
using (var context = app.ApplicationServices.GetRequiredService<ApplicationDbContext>())
{
// perform database delete
context.Database.EnsureDeleted;
//... perform other seed operations
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With