如何在Entity Framework Code First中表示Bridge表

时间:2013-01-03 23:45:32

标签: c# entity-framework ef-code-first entity-framework-4.1

我试图找出如何在两个实体之间表示桥接表(多对多关系) 我正在使用实体框架代码

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

2 个答案:

答案 0 :(得分:13)

简而言之StudentClass之间的此关系类型在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;
    //} 
}