DenLilleMand DenLilleMand - 13 days ago 9
C# Question

Dotnet core 1.1 on linux: Any particular way thats better than others when seeding data with EF Core?

I was thinking about just doing a migration, and seeding the data in that migration. I am not sure if i want seeding to be part of my migrations, maybe there comes a time when i want a clean slate.

Last time i did asp.net about a year ago on windows i had the following implementation:

using System.Collections.Generic;
using System.Data.Entity.Validation;
using Mentor.Models;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
/**
* Author: matti
*/
namespace Mentor.Migrations
{
using System;
using System.Data.Entity;
using System.Data.Entity.Migrations;
using System.Linq;

internal sealed class Configuration : DbMigrationsConfiguration<Mentor.Models.ApplicationDbContext>
{
public Configuration()
{
/*if (System.Diagnostics.Debugger.IsAttached == false)
System.Diagnostics.Debugger.Launch();*/
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed = true;
ContextKey = "Mentor.Models.ApplicationDbContext";
}

protected override void Seed(Mentor.Models.ApplicationDbContext context)
{
try
{
var passwordHasher = new PasswordHasher();
User user1 = new User()
{
UserName = "mattinielsen5@hotmail.com",
PasswordHash = passwordHasher.HashPassword("Denherpderp21!"),
FirstName = "Matti andreas",
LastName = "Nielsen",
Age = 24,
ProfileText = "Lorem ipsum dolor sit amet, minimum delicatissimi ad eos, " +
"ne veniam eirmod voluptatibus vel, ne eam facilisi inciderint. " +
"Ex eleifend recteque delicatissimi eos, ut erat posse etiam pri." +
" Ei qui commune vivendum legendos, augue accusata in vim, mei at" +
" bonorum pericula definitionem. Has ornatus aliquando vulputate " +
"at, nonumes docendi in mel. Ne duo recusabo percipitur, et nam " +
"vitae nostrud cotidieque, cibo liber mel te.",
IsMentor = true,
IsMentee = false,
UndefinedInterests = new List<Interest>
{

},
MentorInterests = new List<Interest>
{

},
... blabla alot of entities ...
context.SaveChanges();
}
catch (DbEntityValidationException e)
{
//some error handling
}
}
}
}


So i want something like a seed method, so i was thinking about making my own seed method being called in startup.cs depending on some environment variable like development. My question is, how do you guys do it - or how would you do it??

EDIT:

I am considering doing it like this, when creating the model:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//One-to-one
modelBuilder.Entity<Account>().HasOne(a => a.Player).WithOne(p => p.Account).HasForeignKey<Player>(p => p.AccountForeignKey);
modelBuilder.Entity<Group>().HasOne(g => g.Role).WithOne(r => r.Group).HasForeignKey<Role>(r => r.GroupForeignKey);
modelBuilder.Entity<GameEvent>().HasOne(e => e.Event);
modelBuilder.Entity<GameEvent>().HasOne(e => e.Game);
modelBuilder.Entity<TeamEvent>().HasOne(e => e.Event);
modelBuilder.Entity<TeamEvent>().HasOne(e => e.Team);
modelBuilder.Entity<GroupEvent>().HasOne(e => e.Event);
modelBuilder.Entity<GroupEvent>().HasOne(e => e.Group);

//one-to-many
modelBuilder.Entity<Player>().HasMany(p => p.Integrations).WithOne(i => i.Player);
modelBuilder.Entity<Player>().HasMany(p => p.Followers);
modelBuilder.Entity<Player>().HasMany(p => p.Activities).WithOne(a => a.Player);
modelBuilder.Entity<Game>().HasMany(g => g.GameEvents).WithOne(ge => ge.Game);
modelBuilder.Entity<Game>().HasMany(g => g.Teams).WithOne(t => t.Game);
modelBuilder.Entity<Team>().HasMany(t => t.TeamEvents).WithOne(te => te.Team);
modelBuilder.Entity<Group>().HasMany(g => g.GroupEvents);

//many to many
modelBuilder.Entity<PlayerGames>().HasKey(pg => new {pg.PlayerId, pg.GameId});
modelBuilder.Entity<PlayerTeams>().HasKey(pt => new {pt.PlayerId, pt.TeamId});
modelBuilder.Entity<PlayerGroups>().HasKey(pg => new {pg.PlayerId, pg.GroupId});

//discriminator values
modelBuilder.Entity<Event>()
.HasDiscriminator<string>("Type")
.HasValue<GameEvent>("GameEvent")
.HasValue<GroupEvent>("GroupEvent")
.HasValue<TeamEvent>("TeamEvent");

CALLING SEED DATA DOWN HERE, that should be fine???
}

Answer

The recommended approach is to run the seeding code within a service scope in Startup.Configure().

It's like this :

using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
       var context = serviceScope.ServiceProvider.GetService<MyContext>();       
       context.Database.Migrate();
       context.EnsureSeedData();
 }

You can see more details about this on below link.

Implementing Seeding EF Core 1.0

Comments