[英]Insert/Update Many to Many Entity Framework . How do I do it?
I'm using EF4 and new to it. 我正在使用EF4和它的新功能。 I have a many to many in my project and cannot seem to work out how to insert or update.
我的项目中有很多对很多,似乎无法解决如何插入或更新。 I have build a small project just to see how it should be coded.
我已经构建了一个小项目,只是为了看它应该如何编码。
Suppose I have 3 tables 假设我有3个表
After adding all the relationship and updated the model via model browser I have noticed that StudentClass does not appear, this seems to be default behaviour. 添加所有关系并通过模型浏览器更新模型后,我注意到StudentClass没有出现,这似乎是默认行为。
Now I need to do both an Insert and Update. 现在我需要同时进行插入和更新。 How do you do it?
你怎么做呢? Any code samples or link where I can download an example, or can you spare 5 mins?
我可以下载示例的任何代码示例或链接,还是可以节省5分钟?
In terms of entities (or objects) you have a Class
object which has a collection of Students
and a Student
object that has a collection of Classes
. 就实体(或对象)而言,您有一个
Class
对象,该对象具有Students
集合和一个具有Classes
集合的Student
对象。 Since your StudentClass
table only contains the Ids and no extra information, EF does not generate an entity for the joining table. 由于您的
StudentClass
表仅包含ID并且没有额外信息,因此EF不会为连接表生成实体。 That is the correct behaviour and that's what you expect. 这是正确的行为,这就是你所期望的。
Now, when doing inserts or updates, try to think in terms of objects. 现在,在进行插入或更新时,请尝试根据对象进行思考。 Eg if you want to insert a class with two students, create the
Class
object, the Student
objects, add the students to the class Students
collection add the Class
object to the context and call SaveChanges
: 例如,如果要插入一个包含两个学生的
Class
,则创建Class
对象, Student
对象,将学生添加到类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();
}
This will create an entry in the Class
table, two entries in the Student
table and two entries in the StudentClass
table linking them together. 这将在
Class
表中创建一个条目,在Student
表中创建两个条目,在StudentClass
表中创建两个条目将它们链接在一起。
You basically do the same for updates. 您基本上也会对更新做同样的事情。 Just fetch the data, modify the graph by adding and removing objects from collections, call
SaveChanges
. 只需获取数据,通过添加和删除集合中的对象来修改图形,调用
SaveChanges
。 Check this similar question for details. 查看此类似问题了解详情。
Edit : 编辑 :
According to your comment, you need to insert a new Class
and add two existing Students
to it: 根据您的评论,您需要插入一个新
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();
}
Since both students are already in the database, they won't be inserted, but since they are now in the Students
collection of the Class
, two entries will be inserted into the StudentClass
table. 由于两个学生都已经在数据库中,因此不会插入它们,但由于它们现在位于
Class
的Students
集合中,因此将在StudentClass
表中插入两个条目。
Try this one for Updating: 试试这个更新:
[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);
}
I wanted to add my experience on that. 我想在此加上我的经验。 Indeed EF, when you add an object to the context, it changes the state of all the children and related entities to Added.
实际上,当您将对象添加到上下文时,它会将所有子项和相关实体的状态更改为“已添加”。 Although there is a small exception in the rule here: if the children/related entities are being tracked by the same context, EF does understand that these entities exist and doesn't add them.
虽然规则中存在一个小例外:如果孩子/相关实体被相同的上下文跟踪,EF确实理解这些实体存在并且不添加它们。 The problem happens when for example, you load the children/related entities from some other context or a web ui etc and then yes, EF doesn't know anything about these entities and goes and adds all of them.
例如,当您从其他某个上下文或web ui等加载子/相关实体然后是,EF不知道有关这些实体的任何内容并且添加所有这些实体时,就会出现问题。 To avoid that, just get the keys of the entities and find them (eg
context.Students.FirstOrDefault(s => s.Name == "Alice"))
in the same context in which you want to do the addition. 为了避免这种情况,只需获取实体的密钥并在要添加的相同上下文中找到它们(例如
context.Students.FirstOrDefault(s => s.Name == "Alice"))
。
I use the following way to handle the many-to-many relationship where only foreign keys are involved. 我使用以下方法来处理只涉及外键的多对多关系。
So for inserting : 所以插入 :
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();
}
}
For deleting , 要删除 ,
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();
}
}
}
In entity framework, when object is added to context, its state changes to Added. 在实体框架中,当将对象添加到上下文时,其状态将更改为“已添加”。 EF also changes state of each object to added in object tree and hence you are either getting primary key violation error or duplicate records are added in table.
EF还会更改在对象树中添加的每个对象的状态,因此您要么获得主键冲突错误,要么在表中添加重复记录。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.