一个学生可以上多个课程,在数据库当中我们一般会定义成三个表,学生表 Student,课程表 Course,学生课程表StudentCourse。 学生课程表,这个表东西就是用来存储学生和课程的关系。因为一个学生可以上多个课程,反过来说就是一门课程也有很多学生参加。
在EF core中我们有两种方式来实现这种多对多的关系。
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
// 一个学生有多个课程
public ICollection<Course> Courses { get; set; }
}
public class Course
{
public int Id { get; set; }
public string Name { get; set; }
//一个课程有多个学生
public ICollection<Student> Students { get; set; }
}
public class MalemaDbContext : DbContext
{
public MalemaDbContext(DbContextOptions<MalemaDbContext> options)
: base(options)
{
this.Database.EnsureCreated();
}
public DbSet<Student> Students { get; set; }
public DbSet<Course> Courses { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Student>().Property(x => x.Name).HasMaxLength(50);
base.OnModelCreating(modelBuilder);
}
}
上面代码会自动生成三张表 Students, Courses, 还有 CourseStudents.
但是因为多对多哪张表我们没有显式定义出来,所以对数据库的一些操作会变得比较不方便。 对于关系表我们没有办法单独删除。 可以通过下面的方式来添加数据
public class ManyToManyExample
{
private readonly MalemaDbContext malemaDbContext;
private readonly IDbContextFactory<MalemaDbContext> dbContextFactory;
public ManyToManyExample(MalemaDbContext malemaDbContext, IDbContextFactory<MalemaDbContext> dbContextFactory)
{
this.malemaDbContext = malemaDbContext;
this.dbContextFactory = dbContextFactory;
}
public void InitData()
{
using (var dbContext = this.dbContextFactory.CreateDbContext())
{
if (dbContext.Students.Count() < 1)
{
var courses = GetCourses();
dbContext.AddRange();
dbContext.SaveChanges();
var students = GetStudents();
foreach (var item in students)
{
item.Courses = courses;
}
dbContext.AddRange(students);
dbContext.SaveChanges();
}
}
}
private static List<Course> GetCourses()
{
var course1 = new Course() { Name = "英语" };
var course2 = new Course { Name = "足球" };
return new List<Course>() { course1, course2 };
}
private static List<Student> GetStudents()
{
var student1 = new Student() { Name = "张三", };
var student2 = new Student() { Name = "李四", };
return new List<Student>() { student1, student2 };
}
}
上面的完整代码可以在分支relationship/many_to_many_1
看到
git clone https://gitee.com/malema/Examples
git checkout relationship/many_to_many_1
ManyToManyExample.cs
public class Course
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<StudentCourse> StudentCourses { get; set; }
}
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<StudentCourse> StudentCourses { get; set; }
}
public class StudentCourse
{
public int Id { get; set; }
public int StudentId { get; set; }
public int CourseId { get; set; }
public Student Student { get; set; }
public Course Course { get; set; }
}
public class MalemaDbContext : DbContext
{
public MalemaDbContext(DbContextOptions<MalemaDbContext> options)
: base(options)
{
this.Database.EnsureCreated();
}
public DbSet<Student> Students { get; set; }
public DbSet<Course> Courses { get; set; }
public DbSet<StudentCourse> StudentCourses { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Student>().Property(x => x.Name).HasMaxLength(50);
base.OnModelCreating(modelBuilder);
}
}
上面代码会同样会生成三张表 Students, Courses, 还有 CourseStudents.
我们可以通过下面的这种方式来添加数据。 因为多对多表也会单独的映射。所以我们可以很方便只对关系进行操作。
public class ManyToManyExample
{
private readonly MalemaDbContext malemaDbContext;
private readonly IDbContextFactory<MalemaDbContext> dbContextFactory;
public ManyToManyExample(MalemaDbContext malemaDbContext, IDbContextFactory<MalemaDbContext> dbContextFactory)
{
this.malemaDbContext = malemaDbContext;
this.dbContextFactory = dbContextFactory;
}
public void InitData()
{
using (var dbContext = this.dbContextFactory.CreateDbContext())
{
if (dbContext.Students.Count() < 1)
{
var courses = GetCourses();
dbContext.AddRange(courses);
dbContext.SaveChanges();
var students = GetStudents();
dbContext.AddRange(students);
dbContext.SaveChanges();
var studentCourse1 = new StudentCourse()
{
StudentId = 1,
CourseId = 1,
};
var studentCourse2 = new StudentCourse()
{
StudentId = 1,
CourseId = 2,
};
var studentCourse3 = new StudentCourse()
{
StudentId = 2,
CourseId = 1,
};
dbContext.AddRange(studentCourse1, studentCourse2, studentCourse3);
}
}
}
private static List<Course> GetCourses()
{
var course1 = new Course() { Name = "英语" };
var course2 = new Course { Name = "足球" };
return new List<Course>() { course1, course2 };
}
private static List<Student> GetStudents()
{
var student1 = new Student() { Name = "张三", };
var student2 = new Student() { Name = "李四", };
return new List<Student>() { student1, student2 };
}
}
上面的完整代码可以在分支relationship/many_to_many_2
看到
git clone https://gitee.com/malema/Examples
git checkout relationship/many_to_many_2
ManyToManyExample.cs