更新多对多关系

时间:2011-05-03 19:46:00

标签: asp.net-mvc-3 automapper entity-framework-4.1

我用几种不同的方式问了几个不同的问题,我还没有得到任何答复。我再次尝试,因为我觉得我的解决方案太复杂了,我一定会错过一些更简单的事情。

在MVC 3应用程序中使用EF 4.1,POCO,DbContext API,AutoMapper和Razor。

我的两个实体之间存在多对多的关系:Proposals和CategoryTags。我可以成功地将(Automapper)一个Proposal映射到我的ProposalViewModel,包括CategoryTags的集合。

在我的视图中,我使用javascript来允许用户通过动态创建元素来添加,更新和删除标记,每个元素都存储所选标记的ID。

我可以成功将我的ViewModel发布回我的控制器,并填充了它的CategoryTags集合(尽管只有每个CategoryTag的ID属性)。

当ViewModel发布回我的控制器时,我不知道如何从ViewModel获取这些标签并将它们添加到我的模型中,以便db.SaveChanges()正确更新数据库。

方式我取得了任何成功,是在映射中断开CategoryTags集合(通过namig以不同方式),迭代每个标记并在我的上下文中手动查找它然后调用.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 个答案:

答案 0 :(得分:4)

唯一可行的方法是手动执行此操作 - 如果需要,您可以阅读full description of the problem。描述与ObjectContext API有关,但DbContext API只是包装器遇到同样的问题(实际上DbContext API在这种情况下会遇到更多问题,因此我将跳过手动设置关系的解决方案)。

简而言之。将数据发布回控制器后,您必须创建新的上下文实例并附加Proposal和相关的CategoryTags。但在此之后,您必须告知上下文您所做的更改。这意味着您必须说明哪些标签已添加到提案中以及哪些标签已被删除。否则上下文无法处理您的更改,因为它不会与数据库中的数据自动合并。

解决此问题的最简单方法是从数据库加载当前Proposal与相关CategoryTags(=您将具有附加实例)并将传入数据合并到附加对象图中。这意味着您将根据发布的值手动删除和添加标记。