0

I have 2 entities with many-to-many relationship.

public class Student{
    public int Id { get; set; }
    public virtual ICollection<Subject> Subjects { get; set; }
}

public class Subject
{
    public int Id { get; set; }
    public virtual ICollection<Student> Students { get; set; }
}

this is the definition of many-to-many mapping between two entities,

modelBuilder.Entity<Student>()
    .HasMany<Subject>(s => s.Subjects)
    .WithMany(c => c.Students)
    .Map(cs =>
    {
        cs.ToTable("SubjectsStudents");
    });

All the subjects are predefined and already in the database. Adding subjects to student is straight forward.

In this, I want to add or remove subjects from each student (update relationship between student and existing subjects).I have the list of subject ids the student should be assigned when update.

How can I update subjects list of student?

Update

This is what I tried.

List<Subject> updatedList = //new list that the student should be assinged;

var entity = ctx.Students
    .Include(n => n.Subjects)
    .Single(n => n.Id == item.Id);

List<Subject> deleteList = //get currently assigned subjects which are not in updatedList;

foreach (Subject subject in deleteList) {
    entity.Subjects.Remove(store);
}

foreach (Subject subject in updatedList)
{
    ctx.Subjects.Attach(subject);
    ctx.Entry(subject).State = EntityState.Unchanged;
}

ctx.Entry(entity).State = EntityState.Modified;
ctx.SaveChanges();

Getting exception: An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.

SajithK
  • 1,014
  • 12
  • 23
  • Like what is the Problem Exactly ? What is the part which you arent getting ? – bhuvin Dec 09 '16 at 10:25
  • Subjects are already in the database. I just want to add or remove relationships. I could not archive this. I update the question with tried code. – SajithK Dec 09 '16 at 10:44
  • So the PrimaryKey on your table is a combination of StudentId & SubjectId right? – Derek Dec 09 '16 at 12:57
  • entity.Stores.Remove(store); ??? stores? – Derek Dec 09 '16 at 13:00
  • @Derek Sorry my mistake. I found an answer, http://stackoverflow.com/a/14460197/443389 with help of Stritof answer. The only drawback there is that I have to fetch each subject from the database before adding it to students collection. Is there any way to achieve this without getting if from DB? – SajithK Dec 09 '16 at 13:05
  • @Derak Yes, The primary key of the intermediate table "SubjectsStudents" is StudentId & SubjectId. The reason to the exception I think is that if there is a subject in updated list which was already assigned to the student. In case the subject entity is already tracked by EF. So trying to attach it again cause the exception. – SajithK Dec 09 '16 at 13:13
  • Yes... thats what i was going to suggest, there is a key violation, basically the a combination of the primary key e.g (1,2) already exists. – Derek Dec 09 '16 at 13:15
  • Instead of checking if the object is already attached I would reccomend to use [`Find()`](https://msdn.microsoft.com/en-us/library/system.data.entity.dbset.find(v=vs.113).aspx) method. It gets the object from the context if it is attached already, otherwise attaches it. – Vitalii Isaenko Dec 09 '16 at 19:40

0 Answers0