C# 使用LINQ更新数据库中的行
ASP核心vs MsSQL 我检查了许多类似问题的答案,但没有找到答案 学生表和课程表与联接表StudentCourse联接:C# 使用LINQ更新数据库中的行,c#,mysql,linq,asp.net-core,entity-framework-core,C#,Mysql,Linq,Asp.net Core,Entity Framework Core,ASP核心vs MsSQL 我检查了许多类似问题的答案,但没有找到答案 学生表和课程表与联接表StudentCourse联接: Student StudentCourse Course ========= ============ ======= PK | ID FK | StudentID PK | ID | Name FK | CourseID | Name 我想为决定更改课程的学生更新/更改j
Student StudentCourse Course
========= ============ =======
PK | ID FK | StudentID PK | ID
| Name FK | CourseID | Name
我想为决定更改课程的学生更新/更改junction StudentCourse表中的课程ID。
我的上下文类:
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);
}
}
根据,有三个步骤更新数据库中的行:
但是它不保存更改。我不明白为什么你不应该选择原语。EF无法跟踪它。您需要选择
StudentCourse
实体。然后,您将能够将其设置为CourseID
,然后保存更改。就像Online123321所写的那样:您需要实体插入原始体。
同时更新要求:
context.Entry(entity).State = EntityState.Modified;
更新
EntityState.Modified不再是必需的-抱歉,我的错误
如果您的表不在上下文中,您可以尝试直接执行SQL:
context.Database.ExecuteSqlRaw(query)
对于您当前的表关系,如果您想更新中间表,我的建议是先删除需要更新的数据,然后执行增行操作。 正如上面的回复中提到的,您不应该使用linq方法进行更新,而应该基于数据库实体 尝试以下代码以实现:
var data = context.StudentCourse.Where(x => x.StudentID == studentId && x.CourseID == oldCourseId).FirstOrDefault();
context.StudentCourse.Remove(data);
StudentCourse newdata= new StudentCourse()
{
StudentID = studentId,
CourseID = newCourse.Id
};
context.StudentCourse.Add(newdata);
context.SaveChanges();
这是什么:
oldCourseIdd
?在这里只是学究。LINQ中的Q代表查询,没有代表更新的U。通常,我们不使用LINQ来更新内容,而是使用它来查询内容
“对结果LINQ to SQL对象中的成员值进行所需的更改。”您发布的代码根本不这样做。oldCourseIdd
来自哪里?这是一个“结果LINQ到SQL对象”吗?这真的是LINQ到SQL吗?在我看来更像实体框架;LINQ到SQL与EF完全不同,只适用于SQL server,而您已经标记了mysql。通过阅读常见问题,我感觉你在错误地学习教程;该代码适用于查询,因为EF使用LINQ,但它不是LtS,所以如果您使用EFIs,请不要遵循LtS教程,这是真的吗?我认为change tracker检测到了它提供的对象的变化,这种黑客行为只有在(例如)你正在创建一个新对象,但希望EF将其视为一个更新的对象时才有必要。是的,我也看到了答案。微软说这是没有必要的。至少我没有发现相反的说法。谢谢你的回答。但问题是我的上下文类没有您在上面看到的StudentCourse
实体。我试图在不直接访问连接表的情况下更改该行。我可以在SQL Management Studio中使用以下命令执行此操作:updatestudentCourseSet CourseId='9A414E30-DA37-48ED-105E-08D8129A967A',其中StudentId='A1F38C12-AE65-464C-C489-08D814F4CDDC'
但如何在VS中执行此操作?我尝试了以下代码:context.StudentModels.FromSqlRaw(“更新studentcourseset CourseId={0},其中StudentId={1}”,course.Id,studentdforall)代码>但它也不起作用。我知道它不起作用,因为我需要使用StudentCourse
实体而不是StudentModels
。因此,似乎我必须使用StudentCourse
实体来进行更改。但必须有另一种方法来做到这一点。EF了解当学生和课程实体很多时:很多如何用中间人表拆分它们,学生有课程列表/课程有学生列表。。如果您想为某个学生更改课程,请从其列表中删除一门课程,然后添加另一门课程,然后自然保存;如果您为StudentCourse添加一个DbSet,则可以对其进行操作,但如果没有它,则应加载一名学生的所有课程,然后删除您不想要的课程,然后添加您需要的课程。也许这就是问题所在;你专注于尝试更新;重点放在删除和插入上;这是你在c#对象意义上的做法(你会删除一个课程,然后添加另一个课程,你不会找到一个课程,然后尝试将其id更改为另一个课程的id)@CaiusJard谢谢你。你的评论很有帮助。谢谢你的回答。问题是在我的上下文中没有DbSet。这就是问题所在。最后我刚刚添加了DbSet。
context.SaveChanges();
context.Entry(entity).State = EntityState.Modified;
context.Database.ExecuteSqlRaw(query)
var data = context.StudentCourse.Where(x => x.StudentID == studentId && x.CourseID == oldCourseId).FirstOrDefault();
context.StudentCourse.Remove(data);
StudentCourse newdata= new StudentCourse()
{
StudentID = studentId,
CourseID = newCourse.Id
};
context.StudentCourse.Add(newdata);
context.SaveChanges();