我已经用几种不同的方式问过这个问题几次了,但我还没有得到任何回应。我再试一次,因为我觉得我的解决方案太复杂了,我一定错过了一些更简单的事情。
在MVC 3应用中使用EF 4.1、POCO、DbContext API、AutoMapper和Razor。
我的两个实体之间有一个多对多的关系:proposal和CategoryTags。我可以成功地将(Automapper)一个Proposal映射到我的ProposalViewModel,包括CategoryTags的集合。
在我的视图中,我使用javascript允许用户通过动态创建元素来添加、更新和删除标记,每个元素都存储所选标记的ID。
我可以成功地将我的ViewModel返回到我的控制器,并填充它的CategoryTags集合(尽管只有每个CategoryTag的ID属性)。
当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在这种情况下遇到更多问题,因此我将跳过手动设置关系的解决方案)。
简而言之。将数据发回控制器后,必须创建新的上下文实例,并附加Proposal
和相关的CategoryTags
。但在此之后,您必须告知上下文您所做的更改。这意味着您必须说明上下文,哪些标签已添加到提案中,哪些已被删除。否则,上下文不能处理您的更改,因为它不与数据库中的数据进行任何自动合并。
解决这个问题的最简单的方法是加载当前的Proposal
与相关的CategoryTags
从数据库(=你将有附加的实例),并合并传入的数据到附加的对象图。这意味着您将手动删除和添加基于张贴值的标签。