Author : MD TAREQ HASSAN
DBSeeder
- create utility class
DBSeeder.cs
- use
context.Database.Migrate()
instead ofcontext.Database.EnsureCreated();
(EnsureCreated()
does not use migrations to create the database and therefore the database that is created cannot be later updated using migrations)
DBSeeder.cs
public class DBSeeder
{
public static void Seed(EmployeeDbContext context)
{
// context.Database.EnsureCreated() does not use migrations to create the database and therefore the database that is created cannot be later updated using migrations
// use context.Database.Migrate() instead
context.Database.Migrate();
if (context.Employees.Any())
{
return;
}
// insert dummy data
context.AddRange(GetDummyEmployeeList());
context.SaveChanges();
}
public static List<Employee> GetDummyEmployeeList()
{
var employees = new List<Employee> {
new Employee{ FirstName = "Foo", LastName = "Bar", Boss = "boss 1", Address = "address 1", DateOfBirth = DateTime.Today.AddYears(-1), Salary = 1_000_000.0 },
new Employee{ FirstName = "first_name 2", LastName = "last_name 2", Boss = "boss 2", Address = "address 2", DateOfBirth = DateTime.Today.AddYears(-2), Salary = 2_000_000.0 },
new Employee{ FirstName = "first_name 3", LastName = "last_name 3", Boss = "boss 3", Address = "address 3", DateOfBirth = DateTime.Today.AddYears(-3), Salary = 3_000_000.0 },
new Employee{ FirstName = "first_name 4", LastName = "last_name 4", Boss = "boss 4", Address = "address 4", DateOfBirth = DateTime.Today.AddYears(-4), Salary = 4_000_000.0 },
new Employee{ FirstName = "first_name 5", LastName = "last_name 5", Boss = "boss 5", Address = "address 5", DateOfBirth = DateTime.Today.AddYears(-5), Salary = 5_000_000.0 },
new Employee{ FirstName = "first_name 6", LastName = "last_name 6", Boss = "boss 6", Address = "address 6", DateOfBirth = DateTime.Today.AddYears(-6), Salary = 6_000_000.0 },
new Employee{ FirstName = "first_name 7", LastName = "last_name 7", Boss = "boss 7", Address = "address 7", DateOfBirth = DateTime.Today.AddYears(-7), Salary = 7_000_000.0 },
new Employee{ FirstName = "first_name 8", LastName = "last_name 8", Boss = "boss 8", Address = "address 8", DateOfBirth = DateTime.Today.AddYears(-8), Salary = 8_000_000.0 },
// ... ... ...
};
return employees;
}
}
Use DBSeeder in Main method of Program
- recommend : use the Configure method only to set up the request pipeline. Application startup code belongs in the Main method. See: Move database initialization code
- get a database context instance from the dependency injection container
- call the seed method, passing to it the context
- dispose the context when the seed method is done
Program.cs
public class Program
{
public static void Main(string[] args)
{
var host = CreateWebHostBuilder(args).Build();
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
var context = services.GetRequiredService<EmployeeDbContext>();
DBSeeder.Seed(context);
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred while seeding the database.");
}
}
host.Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args)
{
return WebHost.CreateDefaultBuilder(args).UseStartup<Startup>();
}
}
Auto Migration
- best approach: https://stackoverflow.com/questions/37780136/asp-core-migrate-ef-core-sql-db-on-startup
- data initialization code should be in Main method
- code below is not recommended because
UpdateDatabase()
is inConfigure()
(moveUpdateDatabase()
to Main method if possible)
Startup.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
UpdateDatabase(app);
// ... ... ...
}
private static void UpdateDatabase(IApplicationBuilder app)
{
using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
using (var context = serviceScope.ServiceProvider.GetService<FooDbContext?())
{
context.Database.Migrate();
}
}
}