У меня возникают трудности с получением вложенной коллекции (в моем случае с тегами) для фиксации обратно в базу данных после передачи в мой контроллер. Я использую 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