LINQ To SQL exception с Attach(): не удается добавить объект с уже существующим ключом

Рассмотрим этот типичный отключенный сценарий:

  • загрузить объект Customer из SQL Server с помощью LINQ to SQL
  • пользователь редактирует объект, а уровень представления отправляет обратно измененный объект.
  • слой данных, используя L2S, должен отправить изменения в SQL Server

Рассмотрим этот запрос LINQ To SQL, целью которого является создание объекта Customer.

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

Вопрос

  • Как вы можете избежать этого исключения?
  • Какая лучшая стратегия для обновления сущности, которая НЕ имеет/хочет/нуждается в свойстве timestamp?

Под оптимальные обходные пути

  • вручную задает каждое свойство в обновленном клиенте первоначальному клиенту.
  • развернуть еще один DataContext

Ответы

Ответ 1

Это связано с тем, что ваш datacontext (db) не может отслеживать один и тот же объект более одного раза. См. этот пост для более подробной информации о том, что происходит.

Один из неясных комментариев внизу этой статьи говорит, чтобы попробовать:

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

Сообщите мне, как это работает для вас, поскольку OP этого сообщения говорит, что это сработало для него...

Ответ 2

Вместо создания нового контекста вы можете сделать это:

public void Update(Customer customer)
{
    Customer oldCustomer= db.Custs.First(c => c.ID == customer.ID);  //retrieve unedited 
    oldCustomer = customer;  // set the old customer to the new customer.
    db.SubmitChanges();  //sumbit to database
}