I'm using EF4 and new to it. 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
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.
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?
This question is related to
c#
entity-framework
many-to-many
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.
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. 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. To avoid that, just get the keys of the entities and find them (e.g. context.Students.FirstOrDefault(s => s.Name == "Alice"))
in the same context in which you want to do the addition.
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 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();
}
}
}
Source: Stackoverflow.com