title: How to insert/update a row using EF?
body: <p>What is the correct way to insert/update a row using Entity Framework?</p>
  
  <p>I know this 3 methods:</p>
  
  <p>1 - using <code>Attach</code></p>
  
  <pre><code>var newSale = _context.ST_Sales.FirstOrDefault(x =&gt; x.SaleId == saleId);
  newSale.Hours = 2;
  _context.ST_Sales.Attach(newSale);
  _context.ObjectStateManager.ChangeObjectState(newSale, EntityState.Modified);
  _context.SaveChanges();
  </code></pre>
  
  <p>2 - using <code>ApplyCurrentValues</code></p>
  
  <pre><code>var newSale = _context.ST_Sales.FirstOrDefault(x =&gt; x.SaleId == saleId);
  newSale.Hours = 2;
  _context.ST_Sales.ApplyCurrentValues(newSale);
  _context.SaveChanges();
  </code></pre>
  
  <p>3 - using <code>EF logic</code></p>
  
  <pre><code>var newSale = _context.ST_Sales.FirstOrDefault(x =&gt; x.SaleId == saleId);
  newSale.Hours = 2;
  _context.SaveChanges(); // EF tracks the newSale obj and knows that was changed
  </code></pre>
  
  <p>And to insert there are one more method witch uses the <code>AddObject</code></p>
  
  <pre><code>var newSale = new ST_Sales();
  newSale.Hours = 2;
  _context.ST_Sales.AddObject(newSale);
  _context.SaveChanges();
  </code></pre>
  
  <p><strong>The problem I'm facing</strong> is an error on the EF saying that the modified row is still in memory.</p>
  
  <p><em>My scenario:</em></p>
  
  <ul>
  <li>20 users can add sales to their own company.</li>
  </ul>
  
  <p>I have a simple table relation:</p>
  
  <pre><code>tbl_Companies { CompanyId, Name }
  tbl_Sales     { CompanyId, Hours, Amount }
  </code></pre>
  
  <p>my <code>Edit View</code> simple get's a <code>sales collection</code> of the current week as</p>
  
  <pre><code>var model = _context.ST_Sales.Where(x =&gt; x.CompanyId == 2);
  return View(model);
  </code></pre>
  
  <p>and on the <code>HttpPost</code> Action I simply loop through each one and save the db changes like</p>
  
  <pre><code>[HttpPost]
  public ViewResult Index(List&lt;ST_Sales&gt; model)
  </code></pre>
  
  <p>and</p>
  
  <pre><code>bool newSale = false;
  foreach( var s in model ) { // let's loop through all
  
      newSale = false;
  
      var sale = _context.ST_Sales.FirstOrDefault(x =&gt; x.SaleId == s.SaleId);
      if( sale == null) {
  
          // sale was not found, let's add it (this happens for todays date
          //    as there is no info yet in the db, but we need to add today's info)
  
          sale = new ST_Sale();
          sale.Company.Id = currentLoggedInUser.companyId;
  
          newSale = true;  // let's say it's a new sale so we can add the new object to the changes to commit
      }
  
      sale.Hours = s.Hours;
      sale.Amount = s.Amount;
  
      if( newSale ) {
          // it's a new sale, let's add the obj to our Entity
          _context.ST_Sales.AddObject(sale);
      } 
      else {
          // no need to do anything, EF is tracking the changes of existing objects
      }
  }
  
  _context.SaveChanges();
  </code></pre>
  
  <p>This works fine for one user... but if I logout and login with a different user, and I can see in the breakpoint that the <code>companyId</code> value is different, soon I commit the changes to be saved I get the weird error:</p>
  
  <blockquote>
    <p>An entity object cannot be referenced by multiple instances of IEntityChangeTracker.</p>
  </blockquote>
  
  <p><strong>What am I doing wrong?</strong></p>
  
  <hr>
  
  <p>I'm creating a new instance in the Controller level like:</p>
  
  <pre><code>public class SalesController : Controller
  {
      private SalesTrackerRepository db = SalesTrackerRepository.Instance;
  
      ...
  }
  </code></pre>
  
  <p>and using the source from <a href="http://samscode.com/index.php/2009/12/making-entity-framework-v1-work-part-1-datacontext-lifetime-management/" rel="nofollow">Sams Code</a></p>
  
  <hr>
  
  <p>Also, I used <a href="http://www.west-wind.com/weblog/posts/2008/Feb/05/Linq-to-SQL-DataContext-Lifetime-Management" rel="nofollow">Rick Strahl</a> code and ending up using:</p>
  
  <pre><code>public class SalesController : Controller
  {
      private SalesTrackerRepository db = 
              SalesTrackerRepositoryFactory.GetWebRequestScopedDataContext&lt;SalesTrackerRepository&gt;();
  
      ....
  
  }
  </code></pre>
  
  <p>And I keep getting the same error :(</p>
  
  <hr>
  
  <p><strong>My tests</strong> are based in the same machine using Chrome and Opera with both different credentials.</p>
  
  <blockquote>
    <p>How can I get this error on such test?</p>
  </blockquote>