come si può seminare una relazione molti-a-molti in EF Core, non è stato possibile trovare nulla in quest'area?
Quindi queste sono le entità
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public virtual List<StudentGrade> StudentGrades { get; set; }
}
public class Grade
{
public int Id { get; set; }
public int Grade { get; set; }
public virtual List<StudentGrade> StudentGrades { get; set; }
}
public class StudentGrade
{
public int GradeId { get; set; }
public Grade Grade { get; set; }
public int StudentId { get; set; }
public Student Student { get; set; }
}
quindi la documentazione ufficiale dice che devi avere un'entità unita (nel mio caso StudentGrade) e questo dovrebbe essere referenziato all'interno delle entità che hanno una relazione molti-a-molti. Ef documentazione di base per molti a molti .
Ora in EF, non dovresti farlo, capiresti quelle cose, e quindi invece di avere l'entità join, faresti semplicemente riferimento a ciascuna entità nell'altra.
Quindi, come puoi seminare questo tipo di relazione in EF Core?
Grazie
Quindi quello che ha funzionato per me è stato sovrascrivere DbContext::OnModelCreating(ModelBuilder modelBuilder)
con qualcosa di simile a questo:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<StudentGrade>()
.HasKey(s => new { s.GradeId , s.StudentId });
var students= new[]
{
new Student{Id=1, Name="John"},
new Student{Id=2, Name="Alex"},
new Student{Id=3, Name="Tom"}
}
var grades = new[]
{
new Grade{Id=1, Grade=5},
new Grade{Id=2, Grade=6}
}
var studentGrades = new[]
{
new StudentGrade{GradeId=1, StudentId=1},
new StudentGrade{GradeId=2, StudentId=2},
// Student 3 relates to grade 1
new StudentGrade{GradeId=1, StudentId=3}
}
modelBuilder.Entity<Student>().HasData(stdudents[0],students[1],students[2]);
modelBuilder.Entity<Grade>().HasData(grades[0],grades[1]);
modelBuilder.Entity<StudentGrade>().HasData(studentGrades[0],studentGrades[1],studentGrades[2]);
base.OnModelCreating( modelBuilder );
}
Ho seguito la logica di inizializzazione personalizzata, come spiegato qui , dal momento che il mio impegno è solo dati per i test e lo sviluppo.
Mi piace fare il seeding in modo sincrono, come vedrai nel codice.
Importante : prima di questo passaggio, eseguo un 'commit' ( context.SaveChanges (); ) con i dati delle entità a cui devo unirmi, quindi EF li selezionerà dal DB con l'ID inserito. È bello se il back-end DB ha un ID autoincrementale.
Di seguito con il tuo esempio (ho pluralizzato i dbSet) e supponendo che tu abbia inserito i dati corretti
var student= context.Students.FirstOrDefault(a => a.Name == "vic");
var grade= context.Grades.FirstOrDefault(b => b.Grade == 2);
var studentGrade = context.StudentsGrades.Include(a => a.Students).Include(b => b.Grades)
.FirstOrDefault(c => c.Students.Name == "vic" && c.Grades.Grade = 2);
if (studentGrade == null)
{
context.StudentsGrades.Add(new StudentGrade
{
StudentId = student.Id,
GradeId = grade.Id
});
}
context.SaveChanges();