我试图找出如何在两个实体之间表示桥接表(多对多关系) 我正在使用实体框架代码
Student:
StudentID int PK
StudentName VARCHAR(50)
Class:
ClassID int PK
ClassName VARCHAR(50)
StudentClass:
StudentID INT PK
ClassID INT PK
我应该使用什么样的最佳类结构在实体框架代码中表示它,如何从桥接表中选择并插入其中。
我应该代表这样的类:
public class Student
{
public int StudentId { get; set; }
public string StudentName { get; set; }
public List<Class> Class { get; set; }
}
public class Class
{
public int ClassId { get; set; }
public string ClassName { get; set; }
public List<Student> Students { get; set; }
}
答案 0 :(得分:13)
简而言之:Student
与Class
之间的此关系类型在EF术语中称为多对多关系。
实体框架以一种很好的方式处理参与多对多关系的表。如果联结表(有时称为桥表,关联表,链接表等)只包含外键而没有其他列,则该表由EF抽象,并且双方获得一个导航属性,暴露另一个的集合。侧。
您需要的是首先为上述表格生成实体模型,或者像下面的帖子Creating a Many To Many Mapping Using Code First中那样定义您的代码优先结构。
基本上,根据您的结构,您需要设置适合您班级关系的方法OnModelCreating
。
protected override void OnModelCreating(DbModelBuilder modelBuilder)
根据您的查询需求,您可以查看以下参考信息:
答案 1 :(得分:4)
在Code First中有很多方法可以表示多对多关系。它实际上取决于您对映射的需求。如果您只需要注册地图,那么到目前为止您所拥有的一切。您正在显示的关系将被Code First识别,并且将自动为您创建一个名为“StudentClasses”的映射表
要在映射表中创建映射,只需执行以下操作:
using(var context = new StudentClassContext())
{
Student aStudent = new Student{ StudentName="Johnny", Class = new Class(){ ClassName="Gym"}}
context.Students.Add(aStudent);
context.SaveChanges();
}
您也可以反向执行此操作:
using(var context = new StudentClassContext())
{
Class aClass = new Class{ ClassName = "Gym", Students = new Student(){ StudentName="Johnny"}}
context.Classes.Add(aClass);
context.SaveChanges();
}
如果您想更加具体和明确地了解关系,可以在重写的上下文OnModelCreating()方法中设置显式映射。这看起来像这样:
public class StudentClassContext
{
public DbSet<Student> Students { get; set; }
public DbSet<Class> Classes { get; set; }
public StudentClassContext()
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Student>()
.HasMany(aStudent => aStudent.Classes) // A student can have many classes
.WithMany(aClass => aClass.Students)); // Many classes can have many students
//.Map(c => c.ToTable("StudentClass); // Set the mapping table to this name
}
}
如果由于某种原因你需要在代码中或在EntityFramework上下文操作之外访问映射表,我会说创建一个专用的map类并使其成为代码中的一等公民:
public class Student
{
//...
}
public class Class
{
//...
}
// New Map Class
public class StudentClassMapRecord
{
public int Id; // Map record PK
public Student Student { get; set; }
public Class Class { get; set; }
public StudentClassMapRecord(Student aStudent, Class aClass)
{
Student = aStudent;
Class = aClass;
}
//Uncomment below if you don't need property navigation
//public int StudentId { get; set; }
//public int ClassId { get; set; }
//public StudentClassMapRecord(int studentId, int classId)
//{
// StudentId = studentId;
// ClassId = classId;
//}
}