【问题标题】:Seed in Entity Framework Core Many-to-Many实体框架核心中的种子多对多
【发布时间】:2019-03-04 12:17:39
【问题描述】:

如何在 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 中播种这种类型的关系?

谢谢

【问题讨论】:

  • 播种您的学生,播种您的成绩,然后播种与这两者相关的StudentGrade 实例。不知道这里有什么困惑。
  • 令人困惑的是,为什么必须有一个加入实体?为什么必须播种 3 个实体而不是 2 个实体,并将一个实体的集合用于另一个拥有的对它的引用?
  • 因为这就是它在 EF Core 中的工作方式。

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


【解决方案1】:

所以对我有用的是用类似这样的东西覆盖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 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 );
}

【讨论】:

    【解决方案2】:

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

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

    重要提示:在此步骤之前,我使用必须加入的实体数据执行“提交”(context.SaveChanges();),因此 EF将从插入了 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();
    

    【讨论】:

    • 我刚刚看到最好将前两句放入'if'中以保存数据库访问
    猜你喜欢
    • 2020-01-26
    • 1970-01-01
    • 1970-01-01
    • 2023-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-06
    • 1970-01-01
    相关资源
    最近更新 更多