删除/更新多对多实体框架。无法让它发挥作用

时间:2010-11-23 20:47:03

标签: entity-framework-4 entity

我使用的是EF4,并且在更新和删除项目时遇到问题。 我对插入很满意,但更新和删除无法弄明白。

假设我有3个表和3个匹配的dto类

  1. ClassRoom表

       ClassID-ClassName 
    
  2. 学生表

       StudentID-StudentName
    
  3. StudentClass表

       StudentID-ClassID
    
    
    ///Happy all works I am using existing students to populate the class. Fine.
    private void InsertClassRoom(ClassRoomDto classRoomDto)
    {
        using (var ctx = new TrainingContext())
        {
            //Convert dto to Entity
            var classRoomEntity = new ClassRoom { ClassID = classRoomDto.ClassId, ClassName = classRoomDto.ClassName };
            foreach (var studentInClass in classRoomDto.Students)
            {
                Student student = ctx.Students.Where(x => x.StudentID == studentInClass.StudentId).SingleOrDefault();
                classRoomEntity.Students.Add(student);
            }
            ctx.AddToClassRooms(classRoomEntity);
            ctx.SaveChanges();
        }
    }
    
  4. 但我有2个场景无法弄清楚该怎么做。

    1. 更新教室名称
    2. 添加1名学生
    3. 更新1名学生的姓名
    4. 从班级中删除学生 我该怎么做?

      这是我的更新尝试:

      private void UpdateClassRoom(ClassRoomDto classRoomDto)
      {
          using (var ctx = new TrainingContext())
          {
              var classRoomEntity = new ClassRoom { ClassID = classRoomDto.ClassId, ClassName = classRoomDto.ClassName };
              foreach (var studentDto in classRoomDto.Students)
              {
                  if (studentDto.StudentId == 0)
                  {
                      //it's a new student add it to the classroom
                      Student student = new Student { StudentID = studentDto.StudentId, StudentName = studentDto.StudentName };
                      classRoomEntity.Students.Add(student);
                  }
                  else
                  {
                      //Alter name of the student
                      Student student = ctx.Students.Where(x => x.StudentID == studentDto.StudentId).SingleOrDefault();
                      //update name
                      student.StudentName = studentDto.StudentName;
                      //? what do I do finish this attach or ???
                 }
              }
              ctx.AddToClassRooms(classRoomEntity);
              ctx.SaveChanges();
          }
      }
      
      public void DeleteStudent(ClassRoomDto classRoomDto)
      {
          using (var ctx = new TrainingContext())
          {
              //lost on how to delete a student in  many to many 
          }
      }
      

1 个答案:

答案 0 :(得分:11)

首先,我假设你知道教室已经存在于数据库中。最简单的方法是首先查询它。您实际插入新ClassRoom条目的原因是您使用ctx.AddToClassRooms(classRoomEntry)。这会将实体附加到上下文,并将EntityState设置为Added

private void UpdateClassRoom(ClassRoomDto classRoomDto)
{
    using (var ctx = new TrainingContext())
    {
        ClassRoom classRoomEntity = ctx.
                                    ClassRooms.
                                    Include("Students").
                                    Single(c => c.ClassID == classRoomDto.ClassId);
        classRoomEntity.ClassName = classRoomDto.ClassName;

        foreach (var studentDto in classRoomDto.Students)
        {
            if (studentDto.StudentId == 0)
            {
                // it's a new student add it to the classroom
                Student student = new Student
                                      {
                                          StudentID = studentDto.StudentId,
                                          StudentName = studentDto.StudentName
                                      };
                classRoomEntity.Students.Add(student);
            }
            else
            {
                // Student exists in the DB, but you don't know whether it's 
                // already part of the student collection for the classroom
                Student student = classRoomEntity.
                                  Students.
                                  FirstOrDefault(s => s.StudentID == studentDto.StudentId);

                if (student == null)
                {
                    // this student is not in the class, fetch it from the DB
                    // and add to the classroom
                    student = ctx.
                              Students.
                              SingleOrDefault(s => s.StudentID == studentDto.StudentId)

                    classRoomEntity.Students.Add(student);
                }

                // Update name
                student.StudentName = studentDto.StudentName;
                // Since student is now part of the classroom student collection
                // and classroom IS attached => student is also attached
            }
        }

        ctx.SaveChanges();
    }
}

为了从thr课程中删除学生,您只需将其从集合中删除(但不要调用ctx.DeleteObject(),因为这会将学生从数据库中删除在你的情况下,上面的代码不会处理这个问题,因为它只会增加新的学生。而不是匹配数据库中的所有学生,而不是你的DTO中的学生,你可以采取一种更简单的方法。清除列表首先,然后添加学生:

private void UpdateClassRoom(ClassRoomDto classRoomDto)
{
    using (var ctx = new TrainingContext())
    {
        ClassRoom classRoomEntity = ctx.
                                    ClassRooms.
                                    Include("Students").
                                    Single(c => c.ClassID == classRoomDto.ClassId);
        classRoomEntity.ClassName = classRoomDto.ClassName;
        classRoomEntity.Students.Clear();

        foreach (var studentDto in classRoomDto.Students)
        {
            Student student;
            if (studentDto.StudentId == 0)
            {
                // it's a new student add it to the classroom
                student = new Student
                              {
                                  StudentID = studentDto.StudentId,
                                  StudentName = studentDto.StudentName
                              };
            }
            else
            {
                student = ctx.
                          Students.
                          SingleOrDefault(s => s.StudentID == studentDto.StudentId)

                // Update name
                student.StudentName = studentDto.StudentName;
            }

            classRoomEntity.Students.Add(student);
        }

        ctx.SaveChanges();
    }
}

这可能是您正在寻找的方法。我特意编写了第一个代码片段,向您展示了如何处理新实体和现有实体的不同情况,但这是第二种(更简单)方法更正确。希望这会有所帮助。