Reputation: 18155
In all the examples and articles I've seen about seeding data using EF Core all of the data is hard-coded. I have a need to seed some data where part of it is variable. My model is:
public class Customer
{
[Key]
public Guid Id { get; set; }
public string ApiKey { get; set; }
}
Specifically, I want the ApiKey
to contain a different value each time the seed operation runs. That way I get a different value for each environment (development, QA, production).
I created a method to generate a unique value and added the following to my OnModelCreating
method.
modelBuilder.Entity<Customer>().HasData(new Customer
{
Id = Guid.NewGuid(),
ApiKey = GenerateApiKey()
});
The problem, as you have probably guessed, is that the call to GenerateApiKey
happens when the migration is created so the value generated by GenerateApiKey
is effectively hard-coded into the InsertData
call.
migrationBuilder.InsertData(
table: "Customers",
columns: new[] { "Id", "ApiKey" },
values: new object[]
{
new Guid("bcde0c82-ad26-47fb-bd5f-1ad552d2b8f0"),
"56+hhUTjPwz0FM9uwYg19M5rfq6aUgmNde15Frn6TFY="
});
In EF 6.x I accomplished this using the Seed
method of my DbMigrationsConfiguration
subclass.
I realize I could modify the migration, but we're at a stage of development where we are dropping and recreating the database during changes and that would require every developer remember to do that when they regenerate the initial migration. I'd rather make it a little more foolproof than that.
Upvotes: 2
Views: 352
Reputation: 4323
You could always run a seed method once your host is ready like so (this is how I do it in 2.1):
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Seed().Run();
}
...
public static class WebHostExtensions
{
public static IWebHost Seed(this IWebHost host)
{
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
var loggerFactory = services.GetRequiredService<ILoggerFactory>();
var context = services.GetRequiredService<MsbContext>();
// do whatever you need here with your data before migrations
...
context.Database.Migrate();
// do whatever you need here with your data after migrations
...
}
}
}
Upvotes: 1