单个 MVC5 编辑页上的父/子 CRUD 操作
本文关键字:CRUD 操作 MVC5 编辑 单个 | 更新日期: 2023-09-27 18:34:35
我有一个使用 EF6 代码优先的 MVC 5 项目。它包括包含复杂子对象列表的模型。我需要能够在父对象的编辑页面上添加、更新和删除子对象,同时保存对父对象的更改。
我在如何在控制器中处理这些操作方面遇到了两难境地。这是相关代码。
模型:
public class Parent
{
public int Id {get;set;}
//other properties
public virtual IList<Child> Children {get;set;}
}
public class Child
{
public int Id {get;set;}
//other properties
public int Parent_Id {get;set;}
[ForeignKey("Parent_Id")]
public virtual Parent Parent {get;set;}
[NotMapped]
public bool toBeDeleted {get;set;}
}
控制器:
[HttpPost]
public ActionResult Edit([Bind(Include = "Id, Children")] Parent p)
{
...
//For some reason children are brought in with Parent_Id = null.
//Manually resetting it fixes this issue.
//Needs to be set before parent = modified for referential integrity
foreach(var c in p.Children)
{
c.Parent_Id = p.Id;
}
context.Entry(p).State = EntityState.Modified;
for(int i = 0; i < p.Children.Count; i++)
{
if(p.c[i].toBeDeleted)
{
Child childToDelete = context.Children.Find(p.c[i].Id);
context.Entry(childToDelete).State = EntityState.Deleted;
i--;
}
else
{
context.Entry(p.c[i]).State = p.c[i].Id > 0 ? EntityState.Modified : EntityState.Added;
}
}
context.SaveChanges();
...
}
我必须在删除后包含"i--",因为父对象已经设置为已修改,任何标记为删除的子对象都会立即从抛出循环的列表中删除。 (我最初有一个 foreach 循环,但当集合大小在循环中间发生变化时,这个问题会导致错误(
虽然我所拥有的有效,但感觉有点像拼凑的修复。在我看来,应该有一种更好的方法来实现这一点,而不是在每次删除后手动减少 for 循环中的迭代器以保持项目正确排列。有没有更好的方法可以做到这一点?有没有办法分别设置每个对象的实体状态,而不会影响相关对象的状态?
怎么样:
p.Children.Where(m => m.toBeDeleted).ToList().ForEach(m => p.Children.Remove(m));
只需从集合中删除子项,实体框架就会将其标记为删除。
此外,对于您的添加条件,如果您为Parent_Id
添加了隐藏字段(如果没有,您应该这样做(,那么子项将设置其Parent_Id
,除非他们是新字段。如果它们是新的,那么仅仅由于在Parent
的Children
集合中,它们将被添加,并且Parent_Id
属性将由实体框架自动设置。最有可能的是,您的问题是尝试保存现有子项,这些子项Parent_Id
属性因未发布而已清空。这将导致完整性错误,因为它在实体框架看来好像您希望将Parent_Id
更改为 null。