【发布时间】:2010-04-02 22:12:16
【问题描述】:
我的数据库中有一个表与另一个表有一对多关系,而另一个表又与第三个表有关系:
父对象
- 身份证
- 名称
- 说明
子对象
- 身份证
- 名称
- 说明
- 父对象ID
- 另一个对象 ID
另一个对象
- 身份证
- 名称
对象被映射到实体框架并通过数据访问类公开。
当要显示的数据与领域对象有很大差异时,似乎建议使用 ViewModel,所以我创建了一个 ViewModel,如下所示:
public class ViewModel {
public IList<ParentObject> ParentObjects { get; set; }
public ParentObject selectedObject { get; set; }
public IList<ChildObject> ChildObjects { get; set; }
}
我有一个显示 ParentObjects 列表的视图,单击时将允许修改 ChildObject 并保存。
<% using (Html.BeginForm()) { %>
<table>
<% foreach (var parent in Model.ParentObjects) { %>
<tr>
<td>
ObjectID [<%= Html.Encode(parent.ID)%>]
</td>
<td>
<%= Html.Encode(parent.Name)%>
</td>
<td>
<%= Html.Encode(parent.Description)%>
</td>
</tr>
<% } %>
</table>
<% if (Model.ParentObject != null) { %>
<div>
Name:<br />
<%= Html.TextBoxFor(model => model.ParentObject.Name) %>
<%= Html.ValidationMessageFor(model => model.ParentObject.Name, "*")%>
</div>
<div>
Description:<br />
<%= Html.TextBoxFor(model => model.ParentObject.Description) %>
<%= Html.ValidationMessageFor(model => model.ParentObject.Description, "*")%>
</div>
<div>
Child Objects
</div>
<% for (int i = 0; i < Model.ParentObject.ChildObjects.Count(); i++) { %>
<div>
<%= Html.DisplayTextFor(sd => sd.ChildObjects[i].Name) %>
</div>
<div>
<%= Html.HiddenFor(sd => sd.ChildObjects[i].ID )%>
<%= Html.TextBoxFor( sd => sd.ChildObjects[i].Description) %>
<%= Html.ValidationMessageFor(sd => sd.ChildObjects[i].Description, "*") %>
</div>
<% }
}
} %>
这一切都很好。我的问题是更新 EF 对象并将更改保存回数据库的最佳方法。我最初尝试过:
[HttpPost]
public ActionResult Edit(ViewModel viewModel) {
ParentObject parent = myRepository.GetParentObjectByID(viewModel.SelectedObject.ID);
if ((!ModelState.IsValid)
|| !TryUpdateModel(parent, "SelectedObject", new[] { "Name", "Description" })) {
|| !TryUpdateModel(parent.ChildObjects, "ChildObjects", new[] { "Name", "Description" })) {
//Code to handle failure and return the current model snipped
return View(viewModel);
}
myRepository.Save();
return RedirectToAction("Edit");
}
当我尝试保存对子对象的更改时,出现此异常:“MyEntities.ChildObject”中的实体参与“FK_ChildObject_AnotherObject”关系。找到 0 个相关的“另一个对象”。 1 '另一个对象' 是预期的。
对 StackOverflow 和一般谷歌搜索的调查让我找到了 this blog post,这似乎描述了我的问题:TryUpdateModel() 不能正确处理嵌套集合。显然,(并且通过调试器确认了这一点)它创建了一个新的 ChildObject 而不是与我实例化上下文中的 EF 对象相关联。
我的 hacky 工作是这样的:
if (viewModel.ChildObjects.Count > 0) {
foreach (ChildObject modelChildObject in viewModel.ChildObjects) {
ChildObject childToUpdate = ParentObject.ChildObject.Where(a => a.ID == modelChildObject.ID).First();
childToUpdate.Name = modelChildObject.Name;
}
}
这似乎工作正常。我问你们这些好人:有正确的方法吗?我尝试按照我上面发布的博客链接制作自定义模型绑定器的建议,但它不起作用(反射存在问题,代码预期存在某些属性),我需要尽快完成。
PS - 我试图清理代码以隐藏特定信息,所以要小心我可能已经搞砸了。我主要只是想知道其他人是否解决了这个问题。
【问题讨论】:
-
很抱歉把这个备份起来,但我遇到了类似的问题。无法弄清楚如何将我的所有数据访问保持在视图、控制器和存储库之间的相同“上下文”中。 .所以我在我的数据库中得到了重复..你找到了做这一切的“正确方法”吗?谢谢
-
我们最终通过在复杂情况下不使用 TryUpdateModel 基本上解决了这个问题。不过,您的问题听起来不同,您可能会考虑从上下文中分离/附加实体。
标签: c# asp.net entity-framework asp.net-mvc-2