Вставка / обновление многих для многих Entity Framework. Как мне это сделать?
Я использую EF4 и новый для него. У меня есть много для многих в моем проекте и, похоже, не может решить, как вставить или обновить. Я построил небольшой проект, чтобы посмотреть, как он должен быть закодирован.
Предположим, у меня есть 3 таблицы
- Класс: ClassID-ClassName
- Студент : StudentID-Имя-Фамилия
- StudentClass: StudentID-ClassID
после добавления всех отношений и обновления модели через браузер моделей у меня есть заметил, что StudentClass не появляется, это, кажется, поведение по умолчанию.
теперь мне нужно сделать как Insert и Update. Как ты это делаешь? Любые примеры кода или ссылки, где я могу скачать пример, или вы можете сэкономить 5 минут?
5 ответов:
в терминах сущностей (или объектов) у вас есть
Class
объект, который имеет коллекциюStudents
иStudent
объект, который имеет коллекциюClasses
. С вашегоStudentClass
таблица содержит только идентификаторы и никакой дополнительной информации, EF не создает объект для присоединяемой таблицы. Это правильное поведение, и это то, что вы ожидаете.теперь, когда вы делаете вставки или обновления, попробуйте думать в терминах объектов. Например, если вы хотите вставить класс с двумя студентами, создайте
попробуйте это для Обновление:
[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); }
Я хотел добавить свой опыт на этом. Действительно, EF, когда вы добавляете объект в контекст, он изменяет состояние всех дочерних и связанных сущностей на Added. Хотя здесь есть небольшое исключение в правиле: если дочерние / связанные сущности отслеживаются одним и тем же контекстом, EF понимает, что эти сущности существуют и не добавляет их. Проблема возникает, когда, например, вы загружаете дочерние/связанные объекты из какого-либо другого контекста или веб-интерфейса и т. д., а затем да, EF ничего не знает об этих сущностях и идет и добавляет все из них. Чтобы избежать этого, просто получить ключи сущностей и найти их (например,
context.Students.FirstOrDefault(s => s.Name == "Alice"))
в том же контексте, в котором вы хотите сделать дополнение.
в Entity framework, когда объект добавляется в контекст, его состояние изменяется на добавлено. EF также изменяет состояние каждого объекта на добавленное в дереве объектов, и поэтому вы либо получаете ошибку нарушения первичного ключа, либо в таблицу добавляются повторяющиеся записи.
Я использую следующий способ обработки отношений "многие ко многим", в которых участвуют только внешние ключи.
и вставка:
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(); } }
на удаление,
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(); } } }