none
Problem with Saving data using EF RRS feed

  • Question

  • Hi,I'm trying to save many to many relationship using code below. When I need to remove relationship it works perfect. But when I need to add relationship between tables then I get the following error:

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

    Here is the code:

    public class UserRepository : GenericDataRepository<User>, IUserRepository
        {
    
            public void SaveManyToManyRelationship(User items)
            {
                using (var context = new Entities())
                {
    
                    var existingUser = context.User.Include("Group")
                       .Where(s => s.UserId == items.UserId).FirstOrDefault<User>();
    
    
                    if (items.ModelEntityState == ModelEntityState.Deleted)
                    {
                        foreach (var item in items.Group.Where(i => i.ModelEntityState == ModelEntityState.Deleted))
                        {
                            var deletedGroups = existingUser.Group.Where(i => i.GroupId == item.GroupId).ToList<Group>();
                            deletedGroups.ForEach(c => existingUser.Group.Remove(c));
                        }
                    }
                    else
                    {
    
                        var addedGroups = items.Group.Where(i => i.ModelEntityState == ModelEntityState.Added).ToList<Group>();
                          
    
                        //5- Add new groups
                        foreach (Group c in addedGroups)
                        {
                            
                           
                                                
                            if (context.Entry(c).State == System.Data.EntityState.Detached)
                            {
                                context.Group.Attach(c);
                            }
    
    
    
              
                            existingUser.Group.Add(c);
                                
    
                               
                            }
                           
                        }
    
                        context.SaveChanges();
    
                    }
    
                }
    
            }

    Please if someone can help me in order to make this finally working. What am I doing worng here. Thanks in advance.

    Almir

    Tuesday, May 12, 2015 5:54 PM

All replies

  • Hi Almir,

    What I believe you need to do to help is to modify your code to see if the entity is already being tracked and modify it rather then attaching it.  I've added some code to your For Each to illustrate this:

    //5- Add new groups
    foreach (Group c in addedGroups)
    	{
                            
    		if (context.Entry(c).State == System.Data.EntityState.Detached)
                {
                    
                    var group = context.Group<T>(c);
            		T attachedEntity = group.Local.SingleOrDefault(e => e.Id == c.Id);  // You need to have access to key
    
            		if (attachedEntity != null) {
                		var attachedEntry = context.Entry(attachedEntity);
               	 		attachedEntry.CurrentValues.SetValues(c);
           			 } else {
                		c.State = EntityState.Modified; // This should attach entity
            			}					
                	}
    
                    existingUser.Group.Add(c);
                                
    			}
                    context.SaveChanges();
    

    Tuesday, May 12, 2015 6:21 PM
  • Sorry, but this doesnot help. It still have an error saying An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key. Thsi is how I implemented your solution (maybe did it wrong way)

    public void SaveManyToManyRelationship(User items)
            {
                using (var context = new Entities())
                {
    
                    var existingUser = context.User.Include("Group").Where(s => s.UserId == items.UserId).FirstOrDefault<User>();
                    if (items.ModelEntityState == ModelEntityState.Deleted)
                    {
                        foreach (var item in items.Group.Where(i => i.ModelEntityState == ModelEntityState.Deleted))
                        {
                            var deletedGroups = existingUser.Group.Where(i => i.GroupId == item.GroupId).ToList<Group>();
                            deletedGroups.ForEach(c => existingUser.Group.Remove(c));
                        }
                    }
                    else
                    {
    
                       var addedGroups = items.Group.Where(i => i.ModelEntityState == ModelEntityState.Added).ToList<Group>();
                        //5- Add new groups
                        foreach (Group c in addedGroups)
                        {
                            /*6- Attach courses because it came from client 
                            as detached state in disconnected scenario*/
                            var groupentry = context.Entry<Group>(c);
    
                            if (groupentry.State == EntityState.Detached)
                            {
                                var set = context.Set<Group>();
                                Group attachedEntity = set.Local.SingleOrDefault(e => e.GroupId == c.GroupId);  // You need to have access to key
    
                                if (attachedEntity != null)
                                {
                                    var attachedEntry = context.Entry(attachedEntity);
                                    attachedEntry.CurrentValues.SetValues(c);
                                }
                                else
                                {
                                    groupentry.State = EntityState.Modified;  // This should attach entity
                                }
                            }
    
                            //if (context.Entry(c).State == System.Data.EntityState.Detached)
                            //{
                            //    context.Group.Attach(c);
                            //}
    
                            //if (context.Entry(c).State == System.Data.EntityState.Detached)
                            //{
                            //    
                            //}
    
    
    
                        //    7- Add course in existing student's course collection
                        existingUser.Group.Add(c);
    
    
    
                          }
                           
                        }
    
                        context.SaveChanges();
    
                    }
    
                }

    Any other idea. Thanks

    Tuesday, May 12, 2015 7:39 PM
  • I did see 1 issue with your code:

    You will need to have "c" passed into your set like this

    Your Code:

     var set = context.Set<Group>();

    Updated Code:

     var set = context.Set<Group>(c);

    Could you try updating this?

    Tuesday, May 12, 2015 10:05 PM
  • Hello Almir,

    As we know, Entity Framework uses a context to manage its persistent data in application, the reason you encounters this exception is that you already add an entity into the context(it may be added in application or loaded from the database), then you are trying to add a same type entity and with a same primary key value, however, as this exception says, we cannot do this.

    1.It is not clear which line in your code causes this exception, you may need to

    2.Debug your code step by step and find out the exact caused entities,

    3.If you find it, check the primary key value and remember it,

    4.Restart the application again, when debugging your SaveManyToManyRelationship method, to check the context to see when the record which has the remembered PK value is loaded and why it is not detached as expected.

    Regards.


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Wednesday, May 13, 2015 2:31 AM
    Moderator