簡體   English   中英

更新聯結表中的數據

[英]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'

所以問題是:

  1. 我的假設正確嗎?
  2. 如何在 LINQ 中編寫此 SQL 命令?

我試過了,但得到了 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM