C# – LINQ To SQL exception with Attach(): Cannot add an entity with a key that is already in use

cconcurrencydatacontextlinq-to-sql

Consider this typical disconnected scenario:

  • load a Customer object from SQL Server using LINQ To SQL
  • user edits the entity, and the presentation tier sends back the entity modified.
  • the data layer, using L2S, must send the changes to SQL Server

Consider this LINQ To SQL query whose intention is to take a Customer entity.

Cust custOrig = db.Custs.SingleOrDefault(o => o.ID == c.ID); //get the original
db.Custs.Attach(c, custOrig); //we don't have a TimeStamp=True property
db.SubmitChanges();                

DuplicateKeyException: Cannot add an entity with a key that is already in use.

alt text

Question

  • How can you avoid this exception?
  • What's the best strategy for updating an entity that does NOT have/want/need a timestamp property?

Sub-Optimal Workarounds

  • manually set each property in the updated customer to the orig customer.
  • spin up another DataContext

Best Answer

This has to do with the fact that your datacontext (db) cannot track the same entity more than once. See this post for more details on what's going on.

One of the obscure comments at the bottom of that post says to try:

public void Update(Customer customer)
{
  NorthwindDataContext context = new NorthwindDataContext();
  context.Attach(customer);
  context.Refresh(RefreshMode.KeepCurrentValues, customer);
  context.SubmitChanges();
}

Let me know how it works out for you, as the OP of that post says it worked out for him...