Asp.net mvc 3 更新多对多关系

Asp.net mvc 3 更新多对多关系,asp.net-mvc-3,automapper,entity-framework-4.1,Asp.net Mvc 3,Automapper,Entity Framework 4.1,我已经用几种不同的方式问过这个问题好几次了,但我还没有得到任何回应。我再次尝试,因为我觉得我的解决方案太复杂了,我肯定错过了一些更简单的事情 在MVC3应用程序中使用EF4.1、POCO、DbContext API、AutoMapper和Razor 我的两个实体之间存在多对多关系:提案和分类标签。我可以成功地将提案映射到我的ProposalViewModel(包括类别标签集合) 在我看来,我使用javascript允许用户通过动态创建元素来添加、更新和删除标记,每个元素存储所选标记的ID 我可以

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

在MVC3应用程序中使用EF4.1、POCO、DbContext API、AutoMapper和Razor

我的两个实体之间存在多对多关系:提案和分类标签。我可以成功地将提案映射到我的ProposalViewModel(包括类别标签集合)

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

我可以在填充了ViewModel的CategoryTags集合的情况下(尽管仅使用每个CategoryTag的ID属性)成功地将ViewModel发布回控制器

当该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")

唯一的工作方法是手动操作-如果需要,您可以阅读。该描述与ObjectContext API相关,但DbContext API只是遇到相同问题的包装器(实际上,DbContext API在此场景中遇到更多问题,因此我将跳过手动设置关系的解决方案)

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


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

唯一有效的方法是手动执行此操作-如果需要,您可以阅读。该描述与ObjectContext API相关,但DbContext API只是遇到相同问题的包装器(实际上,DbContext API在此场景中遇到更多问题,因此我将跳过手动设置关系的解决方案)

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


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

Ladislav,谢谢,这是我需要听到的不幸答案。如果这是唯一的办法,那就这样吧,我期待EF 4.2解决这个问题:)我回答了20多次类似的问题,之后我不得不说,这个问题可能不会有任何自动解决方案。简单地说,如果你有分离的实体,你必须以某种方式说出你做了什么。这与手动执行插入、更新和删除操作相同。你必须知道删除了什么和插入了什么。我认为这是有道理的,如果EF有某种“自动对账器”,它至少可以尝试根据你分离的实体和当前实体之间的差异来确定。很抱歉你回答了这么多次,我很难找到一个关于这个问题的确定答案。拉迪斯拉夫,谢谢,这是我需要听到的不幸的答案。如果这是唯一的办法,那就这样吧,我期待EF 4.2解决这个问题:)我回答了20多次类似的问题,之后我不得不说,这个问题可能不会有任何自动解决方案。简单地说,如果你有分离的实体,你必须以某种方式说出你做了什么。这与手动执行插入、更新和删除操作相同。你必须知道删除了什么和插入了什么。我认为这是有道理的,如果EF有某种“自动对账器”,它至少可以尝试根据你分离的实体和当前实体之间的差异来确定。很抱歉,你回答了这么多次,我很难找到一个关于这个问题的肯定的答案。