[英]update data in the junction table
ASP.Net Core 与 MySQL
Student 表和 Course 表与联结表 StudentCourse 连接:
Student StudentCourse Course
========= ============ =======
PK | ID FK | StudentID PK | ID
| Name FK | CourseID | Name
学生更改了他的课程,因此经理需要更改连接表 StudentCourse 中的 CourseID。
但由于以下原因,我无法直接访问联结表:
public class AppDbContext
{
public DbSet<CourseModel> CourseModels { get; set; }
public DbSet<StudentModel> StudentModels { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<StudentCourse>()
.HasKey(t => new { t.StudentId, t.CourseId });
builder.Entity<StudentCourse>()
.HasOne(sc => sc.Student)
.WithMany(s => s.StudentCourse)
.HasForeignKey(sc => sc.StudentId);
builder.Entity<StudentCourse>()
.HasOne(sc => sc.Course)
.WithMany(s => s.StudentCourse)
.HasForeignKey(sc => sc.CourseId);
}
}
所以我不能直接执行这个 SQL 命令:
UPDATE StudentCourse SET CourseId = '9A414E30-DA37-48ED-105E-08D8129A967A' WHERE StudentId = 'A1F38C12-AE65-464C-C489-08D814F4CDDC'
我想我必须使用内部联接。 我的逻辑是:
[HttpGet]
public IActionResult ChangeCourse(Guid id)
{
IQueryable<CourseModel> courses = courseModel.GetCourses();
ViewBag.Courses = new SelectList(courses, "Id", "Name");
var course = courseModel.GetCourseById(id);
return View(course);
}
[HttpPost]
public IActionResult ChangeCourse(CourseModel newCourse)
{
// I know student's id, so I can get his old course id
Guid oldCourseId = (from ... in ...).SingleOrDefault();
// Then just change and save
oldCourseId = newCourse.Id;
context.SaveChanges();
return RedirectToAction();
}
我有 SQL 命令来获取旧课程 ID:
SELECT CourseId FROM StudentModels L
INNER JOIN StudentCourse R
ON L.Id = R.StudentId
WHERE L.Id = 'A1F38C12-AE65-464C-C489-08D814F4CDDC'
所以问题是:
我试过了,但得到了 ID 列表:
from student in context.StudentModels join cours in context.CourseModels on student.Id equals studentId select cours.Id
我还不擅长 LINQ。 请帮忙。
学生和课程之间似乎存在多对多的关系。 每个学生都遵循零个或多个课程,每个课程都跟随零个或多个学生。 这就是为什么你需要一个接线表
你写了:
一个学生改变他的课程
好吧,由于学生可以学习几门课程,你不能说学生改变了他的课程。 您可以说学生学习了一门新课程,和/或停止学习另一门课程。
如果您遵循实体框架约定,您将拥有类似于以下的类:
class Student
{
public int Id {get; set;}
...
// Every Student follows zero or more Courses (many-to-many)
public virtual ICollection<Course> Courses {get; set;}
}
class Course
{
public int Id {get; set;}
...
// Every Course is followed by zero or more Courses (many-to-many)
public virtual ICollection<Student> Students {get; set;}
}
这是检测多对多关系所需的所有实体框架。 它会自动为您创建一个联结表,并在需要时使用它。
如果要更改实体框架中的任何项目,则必须获取完整的项目,并为相关的 Collections 使用Include
停止学习课程并开始学习新课程:
int studentId = ...
int courseIdToStop = ...
int courseIdToAttend = ...
// get the student to change; include his courses
Student studentToChange = dbContext.Students
.Include(student => student.Courses)
.Where(student => student.Id == studentId)
.FirstOrDefault();
// Stop the course
Course courseToStop = studentToChange.Courses
.Where(course => course.Id == courseIdToStop)
.FirstOrDefault();
if (courseToStop != null)
{
// This Student follows this cours; stop it:
studentToChange.Courses.Remove(courseToStop);
}
Course courseToStart = dbContext.Courses
.Where(course => course.Id == courseIdToStart)
.FirstOrDefault();
// only start the course if course exists and not already following
if (courseToStart != null && !studentToChange.Courses.Contains(courseToStart))
{
studentToChange.Courses.Add(courseToStart);
}
dbContext.SaveChanges();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.