Сохранение вложенной коллекции с помощью MVC 3, EF 4.1, DbContext и AutoMapper - PullRequest
0 голосов
/ 29 апреля 2011

У меня возникают трудности с получением вложенной коллекции (в моем случае с тегами) для фиксации обратно в базу данных после передачи в мой контроллер. Я использую EF 4.1 с DbContext API, MVC 3 и Automapper.

Мои модели:

Partial Public Class Proposal
    Public Property Id As Integer
    Public Property Memo As String
    Public Property EntryDate As Nullable(Of Date)
    Public Overridable Property CategoryTags As ICollection(Of CategoryTag) = New HashSet(Of CategoryTag)

End Class

Public Class ProposalViewModel

    Public Property Id As Integer
    <DataType(DataType.MultilineText)>
    Public Property Memo As String
    <DisplayFormat(ApplyFormatInEditMode:=True, DataFormatString:="{0:d}")>
    Public Property EntryDate As Nullable(Of Date)
    Public Overridable Property CategoryTags As ICollection(Of CategoryTag) = New HashSet(Of CategoryTag)
End Class

Мое представление использует код из следующего поста для добавления тегов: http://jarrettmeyer.com/post/2995732471/nested-collection-models-in-asp-net-mvc-3. По сути, теги создаются путем добавления элементов INPUT с атрибутом имени, установленным в «CategoryTag [0] .Id», «CategoryTag [1» ] .Id "и т. Д. ... и значения этих входов являются действительными идентификаторами для тегов в моей базе данных

Наконец, мой POST-код:

<HttpPost()>
Public Function Edit(ByVal pvm As ProposalViewModel) As ActionResult

    Dim p As New Proposal

    p = AutoMapper.Mapper.Map(Of ProposalViewModel, Proposal)(pvm)

    If (ModelState.IsValid) Then
        db.Entry(p).State = EntityState.Modified
        db.SaveChanges()
        Return RedirectToAction("Index")
    Else
        Return View(pvm)
    End If

End Function

Объект pvm возвращается в мой контроллер со значениями, установленными так, как я бы хотел, чтобы они были. Если я добавлю два тега во время выполнения, то в его коллекции будет два объекта CategoryTag с соответствующими идентификаторами. Проблема заключается в том, что при моем вызове SaveChanges соответствующие записи не создаются в моей таблице отношений «многие ко многим» (в данном случае ProposalCategoryTag).

Есть идеи, что я делаю не так?

UPDATE:

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

<HttpPost()>
Public Function Edit(ByVal pvm As ProposalViewModel) As ActionResult

    Dim p As New Proposal
    Dim tempTag As CategoryTag

    p = AutoMapper.Mapper.Map(Of ProposalViewModel, Proposal)(pvm)

    If (ModelState.IsValid) Then

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

        For Each ct As CategoryTag In pvm.Tags

            tempTag = db.CategoryTags.Find(ct.Id)

            If tempTag Is Nothing Then
                Continue For
            End If

            If p.CategoryTags.Contains(tempTag) Then
                Continue For
            End If

            p.CategoryTags.Add(tempTag)
        Next

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

        Return View(pvm)

    End If

End Function

1 Ответ

0 голосов
/ 02 мая 2011

UPDATE:

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

    <HttpPost()>
    Public Function Edit(ByVal pvm As ProposalViewModel) As ActionResult

        Dim p As New Proposal
        Dim tempTag As CategoryTag

        p = AutoMapper.Mapper.Map(Of ProposalViewModel, Proposal)(pvm)

        If (ModelState.IsValid) Then

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

            For Each ct As CategoryTag In pvm.Tags

                tempTag = db.CategoryTags.Find(ct.Id)

                If tempTag Is Nothing Then
                    Continue For
                End If

                If p.CategoryTags.Contains(tempTag) Then
                    Continue For
                End If

                p.CategoryTags.Add(tempTag)
            Next

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


            Return View(pvm)

        End If

    End Function
...