C# 使用asp.net-mvc2和实体框架编辑和更新复杂viewmodel对象的正确方法
我的数据库中有一个表与另一个表具有一对多关系,该表与第三个表具有关系: 父对象C# 使用asp.net-mvc2和实体框架编辑和更新复杂viewmodel对象的正确方法,c#,asp.net,entity-framework,asp.net-mvc-2,C#,Asp.net,Entity Framework,Asp.net Mvc 2,我的数据库中有一个表与另一个表具有一对多关系,该表与第三个表具有关系: 父对象 身份证 名字 描述 子对象 身份证 名字 描述 父对象 另一个目标 另一个物体 身份证 名字 对象映射到实体框架中,并通过数据访问类公开 当要显示的数据与域对象有很大差异时,似乎建议使用ViewModels,因此我创建了一个ViewModel,如下所示: public class ViewModel { public IList<ParentObject> ParentObjects
- 身份证
- 名字
- 描述
- 身份证
- 名字
- 描述
- 父对象
- 另一个目标
- 身份证
- 名字
public class ViewModel {
public IList<ParentObject> ParentObjects { get; set; }
public ParentObject selectedObject { get; set; }
public IList<ChildObject> ChildObjects { get; set; }
}
当我尝试保存对子对象的更改时,会出现以下异常:“MyEntities.ChildObject”中的实体参与“FK\u ChildObject\u AnotherObject”关系。找到0个相关的“另一个对象”。1应为“另一个对象”
通过对StackOverflow和Google搜索的调查,我发现这似乎可以描述我的问题:TryUpdateModel()不能正确处理嵌套集合。显然,(通过调试器确认这一点)它创建了一个新的ChildObject,而不是从实例化的上下文中与EF对象关联
我的老套做法是:
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-我试图清理代码以隐藏特定信息,因此请注意,我可能已经用水管冲洗了一些东西。我主要是想知道其他人是否解决了这个问题。只是简单地看一下提到FK\u ChildObject\u另一个对象的错误。。。你确定你的EF数据模型中关于另一个对象的所有东西都连接正确了吗 在您的问题中,您只列出了两个表,但此错误表示ChildObject正在与另一个对象建立1到*关系,并且保存时实体中没有一个表导致错误
尝试从场景中删除另一个对象以测试ParentObject和ChildObject之间的任何假定问题,或者尝试将FK_ChildObject_另一个对象关系更改为0..1到*以进行测试。您可以查看使用Omu ValueInjector而不是tryupdate。它可以配置得更智能,尽管我更喜欢按惯例使用它
这里的原始问题不完全清楚。我不确定为什么viewmodel中的子对象首先要从父对象中分离出来?很抱歉,我的简要概述中没有包括第三个表。我已经编辑了原始帖子以包含第三个表格。根据你的建议,我制作了另一个对象表0..1。这将错误更改为:正在从AssociationSet“FK\u ChildObject\u ParentObject”添加或删除关系。对于基数约束,还必须添加或删除相应的“ChildObject”。这似乎意味着EF认为我正在尝试创建另一个ChildObject。。。我甚至尝试完全删除另一个对象的关系,但我仍然得到相同的错误。嗯,好消息是另一个对象现在不在图片中,焦点是它所属的位置,即父对象和子对象之间的关系。您是否仍然通过添加/删除子项来产生此错误?此错误似乎表明您正在处理父对象。例如,您添加了一个父级,但父级/子级关联是*到1,而不是*到0..1。在这种情况下添加家长会要求存在一个孩子,并且可能会产生类似于您的错误。很抱歉再次提出此问题,但我遇到了类似的问题。。无法确定如何在视图、控制器和存储库之间将所有数据访问保持在相同的“上下文”中。。所以我在数据库中得到了重复项。。你找到了做这一切的“正确方法”吗?ThanksWe最终基本上解决了这个问题,在复杂的情况下没有使用TryUpdateModel。不过,您的问题听起来不同,您可能会考虑从上下文中分离/附加实体。
[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");
}
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;
}
}