Исключение LINQ To SQL с Attach (): невозможно добавить объект с ключом, который уже используется - PullRequest
15 голосов
/ 18 ноября 2009

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

  • загрузка объекта 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

Вопрос

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

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

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

Ответы [ 2 ]

23 голосов
/ 18 ноября 2009

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

Один из непонятных комментариев внизу этого поста гласит:

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

Дайте мне знать, как это работает для вас, так как в этом посте говорится, что это сработало для него ...

0 голосов
/ 17 июля 2012

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

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
}
...