update remove mvc many framework collection c# entity-framework many-to-many

c# - remove - Insertar/actualizar muchos a muchos marcos de entidades. ¿Cómo lo hago?



update collection entity framework (5)

Estoy usando EF4 y nuevo en esto. Tengo muchos para muchos en mi proyecto y parece que no puedo resolver cómo insertar o actualizar. Construí un pequeño proyecto solo para ver cómo debería codificarse.

Supongamos que tengo 3 tablas

  1. Clase: ClassID-ClassName
  2. Estudiante: StudentID-FirstName-Apellido
  3. StudentClass: StudentID-ClassID

Después de agregar toda la relación y actualizar el modelo a través del navegador de modelos, noté que StudentClass no aparece, esto parece ser un comportamiento predeterminado.

Ahora necesito hacer un Insert y una actualización. ¿Cómo lo haces? ¿Alguna muestra de código o enlace donde pueda descargar un ejemplo, o puede dedicar 5 minutos?


En el marco de la entidad, cuando se agrega un objeto al contexto, su estado cambia a Agregado. EF también cambia el estado de cada objeto para agregarlo en el árbol de objetos y, por lo tanto, obtiene un error de violación de clave principal o se agregan registros duplicados en la tabla.


Pruebe este para la Actualización:

[HttpPost] public ActionResult Edit(Models.MathClass mathClassModel) { //get current entry from db (db is context) var item = db.Entry<Models.MathClass>(mathClassModel); //change item state to modified item.State = System.Data.Entity.EntityState.Modified; //load existing items for ManyToMany collection item.Collection(i => i.Students).Load(); //clear Student items mathClassModel.Students.Clear(); //add Toner items foreach (var studentId in mathClassModel.SelectedStudents) { var student = db.Student.Find(int.Parse(studentId)); mathClassModel.Students.Add(student); } if (ModelState.IsValid) { db.SaveChanges(); return RedirectToAction("Index"); } return View(mathClassModel); }


Utilizo la siguiente forma para manejar la relación muchos a muchos donde solo están involucradas claves externas.

Entonces para insertar :

public void InsertStudentClass (long studentId, long classId) { using (var context = new DatabaseContext()) { Student student = new Student { StudentID = studentId }; context.Students.Add(student); context.Students.Attach(student); Class class = new Class { ClassID = classId }; context.Classes.Add(class); context.Classes.Attach(class); student.Classes = new List<Class>(); student.Classes.Add(class); context.SaveChanges(); } }

Para eliminar ,

public void DeleteStudentClass(long studentId, long classId) { Student student = context.Students.Include(x => x.Classes).Single(x => x.StudentID == studentId); using (var context = new DatabaseContext()) { context.Students.Attach(student); Class classToDelete = student.Classes.Find(x => x.ClassID == classId); if (classToDelete != null) { student.Classes.Remove(classToDelete); context.SaveChanges(); } } }


Yo quería agregar mi experiencia en eso. Efectivamente EF, cuando agrega un objeto al contexto, cambia el estado de todos los elementos secundarios y entidades relacionadas a Added. Aunque hay una pequeña excepción en la regla aquí: si los niños / entidades relacionadas están siendo rastreados por el mismo contexto, EF entiende que estas entidades existen y no las agrega. El problema ocurre cuando, por ejemplo, cargas los elementos secundarios / entidades relacionadas desde otro contexto o una interfaz web, etc. y luego sí, EF no sabe nada sobre estas entidades y va y las agrega todas. Para evitar eso, simplemente obtenga las claves de las entidades y encuéntrelas (por ejemplo, context.Students.FirstOrDefault(s => s.Name == "Alice")) en el mismo contexto en el que desea hacer la adición.


En términos de entidades (u objetos), tiene un objeto de Class que tiene una colección de Students y un objeto de Student que tiene una colección de Classes . Como su tabla StudentClass solo contiene los Id. Y no hay información adicional, EF no genera una entidad para la tabla de unión. Ese es el comportamiento correcto y eso es lo que esperas.

Ahora, al hacer inserciones o actualizaciones, intente pensar en términos de objetos. Por ejemplo, si desea insertar una clase con dos alumnos, cree el objeto de Class , los objetos de Student , agregue los alumnos a la clase, colección de Students , agregue el objeto de Class al contexto y llame a SaveChanges :

using (var context = new YourContext()) { var mathClass = new Class { Name = "Math" }; mathClass.Students.Add(new Student { Name = "Alice" }); mathClass.Students.Add(new Student { Name = "Bob" }); context.AddToClasses(mathClass); context.SaveChanges(); }

Esto creará una entrada en la tabla de Class , dos entradas en la tabla de Student y dos entradas en la tabla de Class StudentClass uniéndolos.

Básicamente haces lo mismo para las actualizaciones. Simplemente busque los datos, modifique el gráfico agregando y quitando objetos de las colecciones, llame a SaveChanges . Verifique esta pregunta similar para más detalles.

Editar :

Según su comentario, debe insertar una nueva Class y agregarle dos Students existentes:

using (var context = new YourContext()) { var mathClass= new Class { Name = "Math" }; Student student1 = context.Students.FirstOrDefault(s => s.Name == "Alice"); Student student2 = context.Students.FirstOrDefault(s => s.Name == "Bob"); mathClass.Students.Add(student1); mathClass.Students.Add(student2); context.AddToClasses(mathClass); context.SaveChanges(); }

Dado que ambos estudiantes ya están en la base de datos, no se insertarán, pero dado que ahora están en la colección de Students de la Class , se insertarán dos entradas en la tabla StudentClass .