【发布时间】:2020-07-02 05:18:16
【问题描述】:
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'
我想我必须使用 Inner Join。我的逻辑是:
[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();
}
我有获取旧课程 ID 的 SQL 命令:
SELECT CourseId FROM StudentModels L
INNER JOIN StudentCourse R
ON L.Id = R.StudentId
WHERE L.Id = 'A1F38C12-AE65-464C-C489-08D814F4CDDC'
所以问题是:
- 我的假设是否正确?
- 如何在 LINQ 中编写这个 SQL 命令?
我试过了,但得到了 ID 列表:
from student in context.StudentModels join cours in context.CourseModels on student.Id equals studentId select cours.Id
我还不擅长 LINQ。请帮忙。
【问题讨论】:
-
一名学生更改了他的课程,因此经理需要更改联结表 StudentCourse 中的 CourseID。 考虑另一种解决方案 - 在
StudentCourse中添加一列,定义当前记录是实际的或过时的。例如,这可以是 boolean (tinyint)Validity列,其值为 1 或 0 表示该行是实际的或过时的。然后只需使用此附加列的条件。并且不需要更新,学生选择新课程时必须添加新行,学生退出课程时必须将行标记为无效。 -
感谢您的回答。希望我明白你的意思。因为我们学校有很多学生,我担心这种情况下桌子会很大。例如,学生 Kate 正在访问课程 A 和课程 B。所以我们有两行。然后她完成了课程A并进入课程C。我认为最好只修改联结表中的数据:将A更改为C。否则课程A仍然会在表中。我们不会使用这些信息(以前的课程)。
-
因为我们学校有很多学生,我担心在这种情况下表格会很大。 MySQL 中的“巨大”一词大约从 10kk 行开始。我怀疑你会达到它。存储完整历史的好处看起来更有帮助。 我们不会使用这些信息(以前的课程)。 这是当前的情况。您尚未考虑任何分析 - 但 99% 的任务将在未来出现。
标签: c# mysql .net linq asp.net-core