title: Moving instance from one collection to another in EF Core 5
body: <p>I'm fairly new to Entity Framework and running into a bug I don't really understand, despite spending a while Googling and read SO. I'm trying to update a large object in Cosmos, using EF Core 5. The exception I get is:</p>
  <blockquote>
  <p>System.InvalidOperationException: The instance of entity type 'NavigationStack.Previous#NavigationItem' cannot be tracked because another instance with the same key value for {'NavigationStackQuestionnaireId', 'Id'} is already being tracked. When replacing owned entities, modify the properties without changing the instance or detach the previous owned entity entry first. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the conflicting key values.</p>
  </blockquote>
  <p>Basically, what I'm trying to do is remove an instance of the NavigationItem object from one collection and place it in a different collection. Here's the code that does that (Upcoming and Previous have the type List):</p>
  <pre><code>public int Pop()
  {
              if (Upcoming.Count &lt; 1)
                  throw new Exception(&quot;There are no forms left on the stack.&quot;);
  
              // pop the top NavigationItem
              NavigationItem current = Upcoming[0];
              Upcoming.RemoveAt(0);
  
              // put it on the Previous stack unless it's temporary
              if (!current.Temporary)
                  Previous.Insert(0, current);
  
              // return its id
              return current.Target;
  }
  </code></pre>
  <p>So my best guess is that EF doesn't like this because when I insert the instance into the Previous, it's actually creating a new instance. Is that right? How can I get this code to play nice with EF? I tried referring to the instance in question as Upcoming[0] throughout (rather than saving it off into the current variable) but that didn't help.</p>
  <p>I've tried to look through other resources about this error, and the solutions all seem to involve manually detaching the instance in question before updating the parent object via EF. That's not plausible in this case (the instance is buried quite deep) and seems like a violation of separation of concerns in any case.</p>
  <p>Any advice would be much appreciated. Thank you!</p>
  <p>EDIT: adding code as requested!
  The class that seems to be throwing the error:</p>
  <pre><code>public class NavigationItem
      {
          public NavigationItem(int target, bool temporary)
          {
              (Target, Temporary) = (target, temporary);
          }
  
          public int Target { get; private set; }
          public bool Temporary { get; private set; }
      }
  </code></pre>
  <p>Its parent, which holds the logic:</p>
  <pre><code>public class NavigationStack
      {
          // Constructors
          public NavigationStack()
          {
              Previous = new();
              Upcoming = new();
          }
  
          // Public Properties
          public List&lt;NavigationItem&gt; Previous { get; private set; }
          public List&lt;NavigationItem&gt; Upcoming { get; private set; }
  
          public int Pop()
          {
              if (Upcoming.Count &lt; 1) throw new Exception(&quot;There are no forms left on the stack.&quot;);
  
              // pop the top NavigationItem
              NavigationItem current = Upcoming[0];
              Upcoming.RemoveAt(0);
  
              // put it on the Previous stack unless it's temporary
              if (!current.Temporary) Previous.Insert(0, current.CloneObject&lt;NavigationItem&gt;());
  
              // return its id
              return current.Target;
          }
      }
  </code></pre>
  <p>And here's how the top-level class is configured in the DbContext:</p>
  <pre><code>modelBuilder.Entity&lt;Questionnaire&gt;()
                  .OwnsOne(questionnaire =&gt; questionnaire.Navigator, navigator =&gt;
                  {
                      navigator.OwnsMany(n =&gt; n.Previous);
                      navigator.OwnsMany(n =&gt; n.Upcoming);
                  });
  </code></pre>