【发布时间】:2012-11-08 16:06:07
【问题描述】:
我正在使用 MVC4 和 EF 代码优先方法开发一个网站。
我在删除具有一对多关系的实体中的子项时遇到了一些问题。
编辑以清除:在我的编辑视图中,我添加/删除/更新父级子集集合中的现有子级,添加/删除是使用 javascript 完成的。当我在控制器方法的 post 请求中收到更新的父级时,我想同步/更新数据库中的父级和子级实体。 父对象在视图中更新时处于分离状态。因此,当我再次附加父级时,我希望它完成在分离状态期间完成的所有更新。
设置实体关系,以便在从父集合中删除子实体时,子实体也会从子表中删除(级联删除之类的?),这在处于附加状态时有效。
但是,当附加父级并保存更改时,只有添加/更新的子级会在数据库中添加/修改。但是从父集合中删除的子项不会在数据库中删除(我希望它们是)。
如何解决?
实体是:
class Parent
{
public virtual ICollection<Child> Children { get; set; }
}
class Child
{
public string Text { get; set; }
}
这可行,并且将从数据库中删除子项:
void RemoveChildFromCollection()
{
// get the first parent and remove the first child in collection
var context = new DatabaseContext();
var parent = context.Parents.First();
parent.Children.Remove(parent.Children.First());
context.SaveChanges();
}
ControllerMethod: 这不能像上面那样工作,被移除的孩子不会从孩子的表中移除
public ActionResult Edit(Parent parent)
{
var context = new DatabaseContext();
context.Entry(parent).State = System.Data.EntityState.Modified;
context.SaveChanges();
return View();
}
模型构建器设置为在从父集合中删除子表时从子表中删除子实体
// Use Identifying relation. Define complex key for ChildObject containing both Id and
ParentObjectId
modelBuilder.Entity<Child>()
.HasKey(c => new {c.ChildID, c.ParentID});
// Because defining such key will remove default convention for auto incremented Id you must redefine it manually
modelBuilder.Entity<Child>()
.Property(c => c.ChildID)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
// Set cascade delete
modelBuilder.Entity<Parent>()
.HasMany(p => p.Children)
.WithRequired()
.HasForeignKey(c => c.ParentID)
.WillCascadeOnDelete();
【问题讨论】:
-
我在下面的答案中添加了一个代码 sn-p 以使其更清晰。
标签: asp.net-mvc entity-framework ef-code-first