实体框架核心中的种子多对多

时间:2018-09-28 13:21:36

标签: c# entity-framework asp.net-core .net-core entity-framework-core

一个人如何在EF Core中播种多对多关系,而在这一领域找不到任何东西?

这就是实体

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; }
}

所以官方文档说您必须定义一个连接实体(在我的情况下为StudentGrade),并且在具有多对多关系的实体中应引用此实体。 Ef core documentation for many-to-many

现在在EF中,您不必这样做,它就能弄清楚这些事情,因此,不用拥有连接实体,您只需将每个实体相互引用即可。

那么如何在EF Core中播种这种类型的关系?

谢谢

2 个答案:

答案 0 :(得分:2)

所以对我有用的是用类似于以下内容的方法来覆盖DbContext::OnModelCreating(ModelBuilder modelBuilder)

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 Grad{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 );
}

答案 1 :(得分:0)

我遵循自定义初始化逻辑,如here所述,因为我的承诺只是用于测试和开发的数据。

我喜欢以同步方式进行播种,正如您将在代码中看到的那样。

重要:在执行此步骤之前,我对必须连接的实体数据进行了“提交”( context.SaveChanges(); )将从带有插入ID的数据库中选择它们。如果数据库后端具有自动递增的ID,那很好。

在您的示例之后(我对dbSet进行了复数处理),并假设您已插入正确的数据

    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();