Нарушение первичного ключа при добавлении взаимосвязи из множества связанных таблиц в инфраструктуру сущностей MVC 3

Я прочитал множество вопросов здесь, которые на первый взгляд кажутся похожими, но просто не похожи. Массовые извинения, если где-то ответили, но, как я уже сказал, я прочитал множество и не могу найти ответ.

Я использую Entity Framework и MVC 3. Я пытаюсь добавить теги к продуктам в моей структуре сущностей, которые имеют отношение многие ко многим и таблицу, связывающую их с помощью просто двух ключей в таблице ссылок, поэтому EF уплотняет Теги в свойство продукта. Таблицы настроены так:

Product: ProductID [int, первичный ключ], имя и т. Д.

Теги: TagName [строка, первичный ключ]

ProductTags: ProductID, TagName

Таким образом, чтобы получить доступ к ProductTags, я могу просто использовать product.Tags

Это мой код:

dbProduct.Tags.Clear();
foreach (var tag in productModel.Tags)
{
    Data.Tag dbTag = new Data.Tag();
    dbTag.TagName = tag;
    dbProduct.Tags.Add(dbTag);
}

dbProduct - сущность Product, а Data - пространство имен. productModel.Tags - это List<string>

Когда я SaveChanges() Я получаю следующее исключение:

"Нарушение ограничения PRIMARY KEY 'PK_Tags_1'. Невозможно вставить повторяющийся ключ в объект 'dbo.Tags'.\ R \n Описание завершено."

Так что меня по-настоящему привлекает: почему он пытается что-то добавить в dbo.Tags? Мне кажется, это следует просто добавить в теги продукта, а не теги. Я не упоминаю теги где-либо еще в этом методе и поэтому ни в коем случае не пытаюсь добавлять что-либо непосредственно в таблицу тегов. Мне кажется, что в EF что-то настроено неправильно, но я не могу думать, что именно, и это было сгенерировано из базы данных.

Извините еще раз, если это ослепительно очевидно, я чувствую себя довольно глупо. Любая помощь очень ценится.

1 ответ

Решение

Проблема в том, что вы создаете новый Tag объект с существующим первичным ключом. когда SaveChanges() называется EF, обнаруживает изменения объектов, которые уже отслеживаются, и новые объекты добавляются. Так как ваш новый Tag EF не отслеживал объект, он пытается вставить его.

Вы должны явно указать EF, что созданный тег является существующим. Для этого вам нужно прикрепить его.

dbProduct.Tags.Clear();
foreach (var tag in productModel.Tags)
{
    Data.Tag dbTag = new Data.Tag();
    dbTag.TagName = tag;

    db.TagSet.Attach(dbTag);

    dbProduct.Tags.Add(dbTag);
}

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

Другие вопросы по тегам