2011-05-03 121 views
1

我以几种不同的方式提出了几个不同的问题,但我还没有收到任何回复。我再次尝试,因为我觉得我的解决方案过于复杂,我必须错过简单的事情。更新多对多关系

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

我有两个我的实体之间有多对多的关系:Proposals和CategoryTags。我可以成功将提案(Automapper)映射到我的ProposalViewModel,包括CategoryTag的集合。

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

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

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

唯一办法我已经没有成功是断开的映射分类|标签集合(由不同纳米格他们),通过每个标签遍历并手动在我的背景下看它,然后调用。新增( ) 方法。由于种种原因,这很sl which,导致我认为我做错了。

任何人都可以提供任何方向吗?

UPDATE:

对于任何人谁是有兴趣的,我的功能代码:

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

回答

4

唯一的工作方式是手工做这个 - 你可以阅读full description of the problem如果你想。描述与ObjectContext API相关,但DbContext API只是包装器遭遇相同的问题(实际上DbContext API在此场景中遇到更多问题,因此我将跳过手动设置关系的解决方案)。

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

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

+0

Ladislav,Thak你,这是我需要听到的不幸答案。如果这是唯一的方法,那么,我会期待EF 4.2解决这个问题.. :) – 2011-05-03 20:50:00

+0

我回答了类似的问题20+次,之后我不得不说,这可能不会有任何自动解决方案问题。如果你有分离的实体,你必须以某种方式说EF你做了什么。它是一样的,如果你想插入,更新,手动删除。你必须知道什么被删除和插入了什么。 – 2011-05-03 22:41:06

+0

我认为这是有道理的,如果EF有某种“自动调节器”,至少试图根据您的分离实体与当前实体之间的差异来计算出来,那将会很好。 对不起,您必须回答这么多次,我很难找到有关此主题的确认答案。 – 2011-05-04 15:13:07