невозможно добавить объект с ключом, который уже используется - PullRequest
8 голосов
/ 11 января 2010

У меня странная ошибка Cannot add an entity with a key that is already in use Но что раздражает в этой ошибке, так это то, что пользователь не получает подробностей - Кто? Какие? Какой стол? Какая запись является виновником этой ошибки?

Было бы крайне сложно определить его, если вы выполняете много операций над объектами LINQ до .Submit()

Можно ли как-то определить причину этой ошибки?

Ответы [ 4 ]

10 голосов
/ 12 января 2010

Эта ошибка обычно возникает, когда вы создаете новую запись в MetaTable с отношением внешнего ключа, и запись внешнего ключа уже существует.

Например, допустим, у вас есть таблица контактов и таблица адресов, и каждый контакт может содержать несколько адресов. Ошибка возникает при создании новой записи контакта и попытке вручную связать существующую запись адреса с этим новым контактом.

Предполагая, что переданный идентификатор адреса представляет существующую запись адреса, это не работает:

public class Contact
{
    public int Contact_ID { get; set; }
    public string Name { get; set; }
    public Address ContactAddress { get; set; }
    public string Phone { get; set; }
}

public class Address
{
    public int Address_ID { get; set; }
    public string Street { get; set; }
    public string CityState { get; set; }
    public string ZIP { get; set; }
}

public void CreateNewContact(int addressID)
{
    Contact contact = new Contact();

    contact.Name = "Joe Blough";
    contact.ContactAddress.Address_ID = addressID;
    contact.Phone = "(555) 123-4567";

    DataContact.SubmitChanges();
}

Исторически сложилось так, что разработчики SQL обучаются просто передавать значение идентификатора, чтобы произошло волшебство. В LINQ-to-SQL, поскольку активность базы данных абстрагирована, мы должны передать весь объект, чтобы механизм LINQ мог правильно отражать необходимые изменения в ChangeSet. В приведенном выше примере механизм LINQ предполагает, что вы запрашиваете создание новой записи адреса, потому что у него не было с ней работать, когда был выполнен SubmitChanges, и он должен соблюдать договор, установленный связью внешнего ключа. Создается пустая запись адреса с переданным значением идентификатора. Ошибка возникает из-за того, что это значение идентификатора уже существует в таблице данных, а набор изменений не пометил дельту адреса как обновление.

Исправление - передать всю запись, а не только значение идентификатора:

contact.ContactAddress = DataContext.Addresses.Where(a => a.Address_ID == addressID).Single();

Теперь механизм LINQ может правильно пометить входящую запись адреса как существующую и не пытаться воссоздать ее.

1 голос
/ 01 июня 2012

Может быть столбец, к которому вы пытаетесь Attach(), Remove(), Add() или DeleteOnSubmit(), является первичным ключом, и вы пытаетесь добавить или присоединить то же значение снова.

Кроме того, возможно, вы обращаетесь к столбцу значения первичного ключа или внешнего ключа в другом методе, и он еще не закрыт, когда вы пытаетесь вызвать вышеупомянутые методы.

Выше этих методов Attach(), Remove(), Add() или DeleteOnSubmit(), попробуйте снова создать новый экземпляр вашего datacontext и запустить.

0 голосов
/ 16 сентября 2015

Как объяснено в одном из ответов выше, эта ошибка более вероятна из-за попытки вставить запись в таблицу с повторяющимся значением в поле ключа первичного идентификатора. Вы можете решить эту проблему, выбрав / создав другой первичный ключ.

0 голосов
/ 11 января 2010

Похоже, вы выполняете Table.Attach (), а присоединяемый объект имеет ключевое значение, которое L2S уже отслеживает. Это не имеет ничего общего с дубликатом ключа в вашей физической базе данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...