Delete / update many in many objects. Can't make it work

I am using EF4 and have problems with many, many updates and item removal. I am pleased with the insert, but updating and uninstalling cannot understand.

Suppose I have 3 tables and 3 dto classes that correspond

  • ClassRoom table

    ClassID-ClassName 
  • Student table

      StudentID-StudentName 
  • StudentClass Table

      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(); } } 

But I have 2 scenarios that cannot figure out what to do.

  • Update class name
  • Add 1 student
  • Update name for 1 student

Remove student from class.
How to do it?

This is my update attempt:

 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 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 } } 
+6
entity entity-framework-4
source share
1 answer

First of all, I assume that you know that the class already exists in the database. The easiest approach is to request it first. The reason you really get the newly entered ClassRoom entry is because you are using ctx.AddToClassRooms(classRoomEntry) . This binds the object to the context and sets the EntityState to 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 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 // 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(); } } 

To remove a student from the 3D class, you just need to remove him from the collection (but DO NOT FIND the ctx.DeleteObject() call, as this will remove the student from the database. Your example, the above code will not take care of this, since it only adds new ones students: Instead of matching all students who are in the database but not in your DTO, you can use a simpler approach: first clear the list and then add students:

 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 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(); } } 

This is probably the approach you are looking for. I specially wrote the first piece of code to show you various cases of handling new and existing objects, but this is a more correct approach (simpler). Hope this helps.

+11
source share

All Articles