尝试更新实体框架中的记录 无法更改关系,因为一个或多个外键属性不可为空

本文关键字:一个 属性 因为 框架 实体 更新 记录 关系 | 更新日期: 2023-09-27 18:35:42

我整天都在寻找解决这个问题的方法。仍然没有找到解决方案。

尝试使用实体框架更新数据库中的记录时,我收到此错误。

无法更改关系,因为一个或多个外键属性不可为空。对关系进行更改时,相关的外键属性将设置为 null 值。如果外键不支持空值,则必须定义新关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。

public bool PostChangesStudent(Student updatedStudent)
{
    // Get current student from the database.
    var student = _db.Students.Find(updatedStudent.Id);
    if (student != null)
    {   
        // Clear all cources from the ICollection list.   
        student.Courses.Clear();
        foreach (var course in updatedStudent.Courses)
        {
            // Adds the new edited courses
            student.Courses.Add(course);
        }
        // Save changes in database
        _db.Entry(student).State = EntityState.Modified;           
        _db.SaveChanges();
}

正如错误所描述的那样,我删除了课程列表中的旧课程对象,然后我想应该添加一个新关系吗?我只是不知道下一步该怎么做。

你看到的是我从数据库(学生)中获取(未编辑的)对象,以及我可以使用参数(updateStudent)检索的updateStudent对象。

学生和课程模型

public class Student
{
    public int Id { get; set; }
    public string StudentNumber { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; } 

    // Courses
    public virtual ICollection<Course> Courses{ get; set; }
}
public class Course
{
    public int Id { get; set; }
    public int StudentId { get; set; }
    public string CourseName { get; set; }
    public int CourseNumber { get; set; }
}

这是一对多的关系,

我已经使用 Context

类和 ContextInitializer 设置了测试数据,我使用本教程解决了这个问题:

实体框架 6 教程

已经阅读了很多关于这个问题的堆栈帖子,但无法理解该怎么办。.

更新

对不起,我打错了字。.我正在使用 clear 从数据库中获取的原始学生对象中取出课程。

然后我循环访问更新的Student.Courses,它由编辑的课程组成,并将它们映射到学生对象中。

完成后,我想再次将对象保存在数据库中,以具有新课程(更新的课程)。

更新2

在与丹路德维希讨论后,我终于把它弄得:D

以下是要执行的操作:

  1. 像他说的那样删除清除。
  2. 从学生对象中清除课程,如下所示:

    foreach (var course in student.Courses.ToArray())
    {
        _db.Entry(course).State = EntityState.Deleted;
        student.Courses.Remove(course);
    }
    
  3. 循环更新的学生课程并将课程对象添加到学生对象。

    foreach (var course in updatedStudent.Courses) 
    {
        student.Courses.add(course);
    }
    

希望这可以帮助其他人解决这个疯狂的错误!

尝试更新实体框架中的记录 无法更改关系,因为一个或多个外键属性不可为空

我认为问题可能来自这一行:

student.Courses.Clear();

。因为Course有 2 个不可为空的外键属性。当您从Student中清除这些内容时,您正在"更改关系",因此 EF 将尝试将Course.StudentId设置为 null。它不能。因为它是一个不可为空的外键属性。

你真的想删除这些课程吗?如果是这样,请删除它们,而不是从集合中删除它们(或在上下文中将其状态标记为已删除)。

// student.Courses.Clear(); get rid of this line, it is bad for you
foreach (var course in student.Courses.ToArray())
{
    _db.Entry(course).State = EntityState.Deleted;
    student.Courses.Remove(course);
}

正如错误所描述的那样,我删除了课程列表中的旧课程对象...

不,您不会在任何地方删除任何内容。在 EF 中,从一对多集合属性中删除项与删除该项不同。即使从student.Courses集合中删除它们,EF 上下文仍会跟踪这些实体,默认情况下只会尝试将其外键值设置为 null。它不能。因为它是一个不可为空的外键属性。