插入/更新多对多的entity framework。 我该怎么做?
我正在使用EF4和新的。 我在我的项目中有很多很多,似乎无法解决如何插入或更新。 我已经build立了一个小项目,看看它应该如何编码。
假设我有3张桌子
- Class:ClassID-ClassName
- 学生:StudentID-FirstName-Surname
- StudentClass:StudentID-ClassID
添加完所有的关系并通过模型浏览器更新模型后,我注意到StudentClass没有出现,这似乎是默认的行为。
现在我需要做一个插入和更新。 你怎么做呢? 任何代码示例或链接,我可以下载一个例子,或者你可以腾出5分钟?
就实体(或对象)而言,您有一个拥有Students
集合的Class
对象和一个拥有一个Classes
集合的Student
对象。 由于您的StudentClass
表只包含Ids并且没有额外的信息,因此EF不会为连接表生成实体。 这是正确的行为,这就是你所期望的。
现在,当插入或更新时,尝试用对象来思考。 例如,如果要插入两个学生的Class
,请创buildClass
对象, Student
对象,将学生添加到class级Students
集合中,将Class
对象添加到上下文并调用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(); }
这将在Class
表中创build一个条目, Student
表中有两个条目,而StudentClass
表中的两个条目将它们链接在一起。
你基本上做同样的更新。 只需获取数据,通过添加和删除集合中的对象来修改graphics,调用SaveChanges
。 检查这个类似的问题的细节。
编辑 :
根据你的评论,你需要插入一个新的Class
并添加两个现有的Students
:
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(); }
由于两个学生都已经在数据库中,他们不会被插入,但是由于他们现在在Class
的Students
集合中,因此两个条目将被插入到StudentClass
表中。
试试这个更新:
[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,当你添加一个对象到上下文中时,它会把所有子和相关实体的状态改为新增。 尽pipe这里的规则中有一个小例外:如果儿童/相关实体正在被相同的上下文跟踪,EF确实知道这些实体存在并且不会添加它们。 例如,当你从其他上下文或web ui等加载子/相关实体时,问题就会发生,然后是的,EF不知道这些实体的任何内容,并添加所有这些实体。 为了避免这种情况,只需获取实体的键并find它们(例如context.Students.FirstOrDefault(s => s.Name == "Alice"))
在同一个上下文中进行添加。
在entity framework中,当对象被添加到上下文时,其状态更改为添加。 EF还会更改每个对象的状态以添加到对象树中,因此您要么获取主键违规错误,要么在表中添加重复的logging。
我使用下面的方式来处理只涉及外键的多对多关系。
所以插入 :
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(); } } }