简体   繁体   English

更新联结表中的数据

[英]update data in the junction table

ASP.Net Core vs MySQL ASP.Net Core 与 MySQL

Student table and Course table are joined with the junction table StudentCourse: Student 表和 Course 表与联结表 StudentCourse 连接:

Student      StudentCourse       Course
=========    ============        =======
PK | ID      FK | StudentID       PK | ID
   | Name    FK | CourseID           | Name

A student changes his course so manager needs to change CourseID in the junction table StudentCourse.学生更改了他的课程,因此经理需要更改连接表 StudentCourse 中的 CourseID。

But I don't have direct access to the junction table due to:但由于以下原因,我无法直接访问联结表:

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

So I can't execute this SQL command directly:所以我不能直接执行这个 SQL 命令:

UPDATE StudentCourse SET CourseId = '9A414E30-DA37-48ED-105E-08D8129A967A' WHERE StudentId = 'A1F38C12-AE65-464C-C489-08D814F4CDDC'

I think I have to use Inner Join.我想我必须使用内部联接。 My logic is:我的逻辑是:

    [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();
    }

I have the SQL command to get an old course id:我有 SQL 命令来获取旧课程 ID:

SELECT CourseId FROM StudentModels L
INNER JOIN StudentCourse R
ON L.Id = R.StudentId
WHERE L.Id = 'A1F38C12-AE65-464C-C489-08D814F4CDDC'

So the questions are:所以问题是:

  1. Are my assumptions correct?我的假设正确吗?
  2. How to write this SQL command in LINQ?如何在 LINQ 中编写此 SQL 命令?

I tried this but got the list of Ids:我试过了,但得到了 ID 列表:

from student in context.StudentModels join cours in context.CourseModels on student.Id equals studentId select cours.Id

I'm not good at LINQ, yet.我还不擅长 LINQ。 Please help.请帮忙。

There seems to be a many-to-many relation between Students and Courses.学生和课程之间似乎存在多对多的关系。 Every Student follows zero or more Courses, and every Course is followed by zero or more Students.每个学生都遵循零个或多个课程,每个课程都跟随零个或多个学生。 That why you need a junction table这就是为什么你需要一个接线表

You wrote:你写了:

A student changes his course一个学生改变他的课程

Well, as Students can follow several Courses, you cannot say that a Student changes his course.好吧,由于学生可以学习几门课程,你不能说学生改变了他的课程。 You can say that a Student follows a new Course, and/or stops following another Course.您可以说学生学习了一门新课程,和/或停止学习另一门课程。

If you have followed the entity framework conventions, you will have classes similar to the following:如果您遵循实体框架约定,您将拥有类似于以下的类:

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

This is all entity framework needs to know to detect your many-to-many relationship.这是检测多对多关系所需的所有实体框架。 It will automatically create a junction table for you and use it whenever needed.它会自动为您创建一个联结表,并在需要时使用它。

If you want to change any item in entity framework, you'll have to fetch the complete item, and use Include for related Collections如果要更改实体框架中的任何项目,则必须获取完整的项目,并为相关的 Collections 使用Include

To Stop following a course and start following a new Course:停止学习课程并开始学习新课程:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM