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

use*_*969 6 entity entity-framework-4

我使用EF4并且有多项更新和删除项目的问题.我很高兴插入,但更新和删除无法搞清楚.

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

  1. ClassRoom表

       ClassID-ClassName 
    
    Run Code Online (Sandbox Code Playgroud)
  2. 学生表

       StudentID-StudentName
    
    Run Code Online (Sandbox Code Playgroud)
  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();
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

但我有2个场景无法弄清楚该怎么做.

  1. 更新教室名称
  2. 加1名学生
  3. 更新1名学生的姓名

从班级中删除学生.
我该怎么做?

这是我尝试更新:

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 
    }
}
Run Code Online (Sandbox Code Playgroud)

Yak*_*ych 11

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

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

为了从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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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