Обновление отношения «многие ко многим» - PullRequest
1 голос
/ 03 мая 2011

Я задавал вопрос несколько раз, несколькими способами, и пока не получил ни одного ответа.Я пытаюсь снова, потому что чувствую, что мое решение слишком запутанное и мне не хватает чего-то более простого, чтобы сделать.

Использование EF 4.1, POCO, DbContext API, AutoMapper и Razor в приложении MVC 3.

У меня есть отношения многие ко многим из двух моих сущностей: предложений и категорийных тегов.Я могу успешно сопоставить (Automapper) предложение с моей ProposalViewModel, включая коллекцию тегов категории.

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

Я могу успешно отправить свою ViewModel обратно на мой контроллер с заполненной коллекцией CategoryTags (хотя только со свойством ID для каждого CategoryTag).

Когда эта ViewModel публикуется обратно в мойконтроллер, я не знаю, как получить эти теги из ViewModel и добавить их в мою модель таким образом, чтобы db.SaveChanges () правильно обновлял базу данных.

Только способ, которым я добился какого-либо успеха, - это отключить коллекцию CategoryTags при отображении (по-разному называя их), перебрать каждый тег и вручную найти его в моем контексте, а затем вызвать метод .add ().Это небрежно по ряду причин, которые заставляют меня думать, что я делаю это неправильно.

Кто-нибудь может предложить какое-либо направление вообще?

ОБНОВЛЕНИЕ:

Для всехкому интересно, мой функциональный код:

            Dim p As New Proposal
            Dim tempTag As CategoryTag
            p = AutoMapper.Mapper.Map(Of ProposalViewModel, Proposal)(pvm)

            db.Proposals.Attach(p)
            db.Entry(p).Collection("CategoryTags").Load()

            For Each ct In pvm.Tags
                tempTag = db.CategoryTags.Find(ct.Id)

                If tempTag Is Nothing Then
                    Continue For
                End If

                If ct.Tag = "removeMe" Then
                    p.CategoryTags.Remove(tempTag)
                    Continue For
                End If

                p.CategoryTags.Add(tempTag)
            Next


            db.Entry(p).State = EntityState.Modified
            db.SaveChanges()
            Return RedirectToAction("Index")

1 Ответ

4 голосов
/ 04 мая 2011

Единственный способ работы - сделать это вручную - вы можете прочитать полное описание проблемы , если хотите.Описание относится к ObjectContext API, но DbContext API - просто оболочка, испытывающая те же проблемы (на самом деле DbContext API испытывает еще больше проблем в этом сценарии, и поэтому я пропущу решение с настройкой отношений вручную).

Короче.Как только вы отправляете свои данные обратно в контроллер, вы должны создать новый экземпляр контекста и присоединить ваш Proposal и полученный CategoryTags.Но после этого вы должны сообщить контексту об изменениях, которые вы сделали.Это означает, что вы должны указать контекст, какие теги были добавлены в предложение, а какие были удалены.В противном случае контекст не может обработать ваши изменения, потому что он не выполняет автоматического слияния с данными в базе данных.

Самый простой способ решить эту проблему - загрузить текущую Proposal с связанной CategoryTags из базы данных (= у вас будетвложенные экземпляры) и объединить входящие данные в графе прикрепленных объектов.Это означает, что вы будете вручную удалять и добавлять теги на основе опубликованных значений.

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