C
C#10mo ago
joren

Data seeding database

So currently in my program.cs I have the following code:
// Seed the database, disable once done.
using (var scope = app.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
DataContext context = services.GetRequiredService<DataContext>();

if(context.Database.EnsureCreated())
{
var dataSeeder = new DataSeeder(context);
dataSeeder.SeedData();
}
}
catch (Exception ex)
{
Console.WriteLine($"Error occurred while seeding the database: {ex.Message}");
}
}
// Seed the database, disable once done.
using (var scope = app.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
DataContext context = services.GetRequiredService<DataContext>();

if(context.Database.EnsureCreated())
{
var dataSeeder = new DataSeeder(context);
dataSeeder.SeedData();
}
}
catch (Exception ex)
{
Console.WriteLine($"Error occurred while seeding the database: {ex.Message}");
}
}
Now, seeding only makes sense in a development environment and only has to be executed once. So would this be a proper way to go about it? My DataSeeder class basically creates objects of all my models, gives them mock values, and that I save to the database.
40 Replies
joren
joren10mo ago
To my understanding, once I call SaveChanges() on my DataContext object, that's when they will staged for the next migration, please correct me if im wrong. For instance in my
public void SeedData()
{
SeedPokemonOwners();
_context.SaveChanges();
}
public void SeedData()
{
SeedPokemonOwners();
_context.SaveChanges();
}
The moment I do _context.SaveChanges();, all the changes I pushed to the context with: _context.TableName.AddRange( /* data here */ ) gets staged for the next migrations.
Baturhan
Baturhan10mo ago
Hello @joren, you can check your enviorenment in program.cs using app.Environment.IsDevelopment() if this returns true you are in development, if the case is only debuggin #if DEBUG #end if you can use this. So when you release the application your enviorenment is going to be production(or the setting you set before) and the db is not going to be seed anymore Savechanges method just redirect your query to the db, it's not related with migration at all
joren
joren10mo ago
Migrations are strictly about model changes and its relations and nothing to do with the values inside those tables then I assume would make sense actually, as seeding wouldnt be migrating anything what dictates the value it returns, the profile we use to run it ?
joren
joren10mo ago
so this one, in release it would be False then I assume
No description
joren
joren10mo ago
Eh, I guess its the launchSettings.json that dictates it
{
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5116",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7048;http://localhost:5116",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
}
{
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5116",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7048;http://localhost:5116",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
}
Baturhan
Baturhan10mo ago
Yes, there is a environment variables you need to use
No description
joren
joren10mo ago
"ASPNETCORE_ENVIRONMENT": "Development" Makes sense, so lets say its on development as it is now, would it try to seed it every time I run it ? I assume so, which would make the startup time pretty inefficient I might just add some compile time constant, that I can flip from True to False to disable seeding after the initial seeding locally...
Baturhan
Baturhan10mo ago
if that variable is set to development yes, If you don't want ta seed again and again, you could check the data with "any" method. If you try to execute your program in release mode it should be changed I guess, let me check it
joren
joren10mo ago
Any() would be on a table, what if seeding was done manually and therefore is not 100% complete, then doing it on just one table would be wrong you'd have to do a .Any() check on each table, to see if it contains any data, if one of them does not, just seed it, else skip it Would be cool if I could somehow iterate over the types in the Models folder, call .Any() on each, not sure if thats achievable in C#. It has reflection, so it is doable I just checked
Baturhan
Baturhan10mo ago
are you even trying to execute the db commands parallel? Any() just returns, if there is any data in the table. IF you added it it will true, thus you dont need to add any data to seed and you will return/continue
joren
joren10mo ago
I mean prior to seeding, when the program starts, lets assume the db is seeded already
Baturhan
Baturhan10mo ago
Even if you add your data manually when thread comes to Any() method it's going to return true or false according to it
joren
joren10mo ago
I want to check if it's seeding yes, but that'd mean I'd have to call .Any on each table individually imagine you have 100 tables, no one will call .Any on each table to check if it has data. prior to seeding I could I guess, but then it always goes into the proces of seeding. Then I assume it should be seeded, and actually seed the table if its not populated
Baturhan
Baturhan10mo ago
Yes unfortunetly. Well in that case If you are adding any data to the 100 tables manually you already have long code, an any method wouldn't hurt ya? you can register your code to the applicationstart event, thus it's absolutely going to work once. it'd be useless if you define a variable to the program cs because it only works once already
joren
joren10mo ago
yeah true, one more thing thats bugging me:
Want results from more Discord servers?
Add your server