我有以下代码从父母那里删除子女和孙子女
MyEntities dbContext = new MyEntities();
var parent = dbContext.Parents
.Include(x => x.Childrens.Select(y => y.GrandChildrens))
.Where(x => x.ParentID == 1)
.SingleOrDefault();
// get first child
var child = parent.Childrens.First();
// remove all grand childrens from child
var count = child.GrandChildrens.Count;
for (int i = 0; i < count; i++)
{
child.GrandChildrens.Remove(child.GrandChildrens.ElementAt(0));
}
// remove child from parent
parent.Childrens.Remove(child);
// save changes
dbContext.SaveChanges();
以上代码抛出异常
经过几篇文章后,似乎我必须将Entity的状态标记为已删除,而不是从集合中删除实体。操作失败:无法更改关系,因为 一个或多个外键属性是不可为空的。当一个 改变了关系,相关的外键属性是 设置为空值。如果外键不支持空值, 必须定义新的关系,外键属性必须是 分配了另一个非空值,或者不相关的对象必须是 删除。
MyEntities dbContext = new MyEntities();
var parent = dbContext.Parents
.Include(x => x.Childrens.Select(y => y.GrandChildrens))
.Where(x => x.ParentID == 1)
.SingleOrDefault();
// get first child
var child = parent.Childrens.First();
// remove all grand childrens from child
var count = child.GrandChildrens.Count;
for (int i = 0; i < count; i++)
{
dbContext.Entry<GrandChild>(child.GrandChildrens.ElementAt(0)).State = EntityState.Deleted;
}
// remove child from parent
dbContext.Entry<Child>(child).State = EntityState.Deleted;
// save changes
dbContext.SaveChanges();
上面的代码
但我有疑问
1&GT;如何启用级联删除,以便我不必显式删除GrandChildrens?我正在使用DB第一种方法。
2 - ;如果我们将实体添加到集合中并调用dbContext.SaveChanges(),那么EF会保存新添加的实体,即使我们没有明确地将实体的状态标记为Added
。为什么删除操作不适用?为什么我们必须将实体的状态明确设置为Deleted
答案 0 :(得分:1)
啊,我一直在ORM之间蹦蹦跳跳......我更喜欢NHibernate的其余原因之一,已经有了关于级联删除孤儿的回复,这些反应不在EF6中,但显然可以在EF Core中使用并期待EF7 ......
EF6需要将实体标记为已删除,因为它仍然缺少孤立跟踪的概念。 :(
的略微冗长的变体
var child = parent.Childrens.First();
child.GrandChidrens.ToList().ForEach(x=>dbContext.Entity(x).State = EntityState.Deleted);
dbContext.Entity(child).State = EntityState.Deleted;
parent.Childrens.Remove(child);
你可以试试EF Core,虽然它有很多其他的龙......
答案 1 :(得分:0)
当您在Children
和Grandchildren
之间声明外键关系时,您可以设置删除规则。您可以在SQL Management Studio中执行此操作。只需选择 Cascade 即可。现在,当您删除父表中的记录时,SQL Server将删除子表中的所有相关记录。
我只能猜测。如果您不需要删除记录,但只想破坏关系怎么办?你会用什么方法?方法ICollection.Remove
看起来像个好人。所以这只是EF作者的选择。