title: EF Code First, generic update fails due to 'Can't Insert duplicate key in object' for twice separated navigation property
body: <p><strong>SOLVED: It was because each of my service classes had their own context associated with them, I just stored the context in HttpContext and made did DI into the repository</strong></p>
  
  <p>I've got 3 classes:</p>
  
  <pre><code> public class Group : Entity
  {
      public Guid Id { get; set; }
      //other simple props
      public virtual GroupType GroupType { get; set; }
  
      public virtual ICollection&lt;User&gt; Users { get; set; }
  }
   public class GroupType: Entity
  {
      public Guid Id { get; set; }
      //other simple props
  }
  
   public class User: Entity
  {
      public Guid Id { get; set; }
      //other simple props
  
      public virtual ICollection&lt;Group&gt; Groups { get; set; }
   }
  </code></pre>
  
  <p>And my fairly standard generic CRUD methods:</p>
  
  <pre><code>public void Insert(TClass entity)
      {
          if (_context.Entry(entity).State == EntityState.Detached)
              _context.Set&lt;TClass&gt;().Attach(entity);
  
          _context.Set&lt;TClass&gt;().Add(entity);
          _context.SaveChanges();
      }
  
  public void Update(TClass entity)
      {
          DbEntityEntry&lt;TClass&gt; oldEntry = _context.Entry(entity);
  
          if (oldEntry.State == EntityState.Detached)
              _context.Set&lt;TClass&gt;().Attach(oldEntry.Entity);
  
          oldEntry.CurrentValues.SetValues(entity);
  
          _context.SaveChanges();
      }
  
  public bool Exists(TClass entity)
      {
          bool exists = false;
  
          PropertyInfo info  = entity.GetType().GetProperty(GetKeyName());
          if (_context.Set&lt;TClass&gt;().Find(info.GetValue(entity, null)) != null)
              exists = true;
  
          return exists;
      }
  
  public void Save(TClass entity)
      {
          if (entity != null)
          {
              if (Exists(entity))
                  _repository.Update(entity);
              else
                  _repository.Insert(entity);
          }
      }
  </code></pre>
  
  <p>I try and run this code:</p>
  
  <pre><code>public string TestCRUD()
      {
  
          UserService userService = UserServiceFactory.GetService();
          User user = new User("Test", "Test", "Test", "TestUser") { Groups = new Collection&lt;Group&gt;() };
  
          userService.Save(user);
  
          GroupTypeService groupTypeService = GroupTypeServiceFactory.GetService();
          GroupType groupType = new GroupType("TestGroupType2", null);
  
          groupTypeService.Save(groupType);
  
          GroupService groupService = GroupServiceFactory.GetService();
          Group group = new Group("TestGroup2", null) { GroupType = groupType };
          groupService.Save(group);
  
          user.Groups.Add(group);
          userService.Save(user);
  
      }
  </code></pre>
  
  <p>When I get to the last line:</p>
  
  <pre><code> userService.Save(user);
  </code></pre>
  
  <p>I get this error:</p>
  
  <blockquote>
    <p>Violation of PRIMARY KEY constraint 'PK_<em>GroupTypes</em>_00551192'. Cannot insert duplicate key in object 'dbo.GroupTypes'.
    The statement has been terminated.</p>
  </blockquote>
  
  <p>So it looks like it's trying to insert a new groupType even though it was already inserted.</p>
  
  <p>Edit: All my class constructors automatically set a new Guid to the Id property.</p>
  
  <h2><strong>EDIT:</strong></h2>
  
  <hr>
  
  <p>I just ran tests by calling <code>.Save()</code> twice on each object, so before it exists in the context/db and once after. The results seem strange:</p>
  
  <ul>
  <li>First Time I call <code>.Save()</code> on <em>groupType</em> object: State is <em>Detached</em> (expected).</li>
  <li>Second time w/no changes to it: State is <em>Unchanged</em> (expected and proves that change tracking is occurring on the in memory object even though I didn't requery it from context).</li>
  <li>First Time I call <code>.Save()</code> on <em>group</em> object (with GroupType set to
  the already saved GroupType): Group State is <em>Detached</em> (expected),
  GroupType state is <em>Detached</em> (<strong>not expected, why is it detached
  here when I already saved it and it was being tracked?</strong>)</li>
  <li>Second Time w/no changes: Both Group and GroupType stats are
  <em>unchanged</em> (expected).</li>
  <li>First Time I call <code>.Save()</code> on <em>user</em> object: State is <em>Detached</em>
  (expected).</li>
  <li>Second Time after calling user.Groups.Add(group) with the saved
  group: User is <em>unchanged</em> (expected), Group is <em>Added</em> (expected), GroupType is <em>Added</em> (<strong>not expected, why is this being marked as Added it's been saved and supposedly is tracked both individually and as part of the group object?</strong>)</li>
  <li>Finally I tried marking the groupType entry as unchanged, and the same duplicate key error occurred this time for the Group object, consistent since it's also added but not expected.</li>
  </ul>
  
  <p>So, 1) why do existing objects act like they aren't being change-tracked when added to a collection navigation property, but in a simpler case, like calling it on the group object twice, the groupType nav prop is still change-tracked and not added twice, in both cases I never re-query to get the object from db. </p>
  
  <p>Finally, 2) what is an efficient way around this behavior? I don't really want to manually set nav properties entity states as unchanged because I can't guarantee that they aren't trying to add a non-existing entity, but at the same time it seems really inefficient to call <code>.Save()</code> on each group and each group type inside the user <code>.Save()</code> OR query each of them from the database. </p>