我正在创建一个代码,我想在其中使用级联删除父对象及其所有子对象,以减少正在执行的删除操作的数量。
所以我有两个这样的实体
public class Parent
{
public long ParentId { get; set; }
public string ParentName { get; set; }
public virtual ICollection<Child> Children { get; set; }
}
子实体看起来像
public class Child
{
public long ChildId { get; set; }
public long? ParentId { get; set; }
public string ChildName { get; set; }
}
我创建了TypeConfiguration
为了使用级联删除
public class ParentTypeConfiguration : EntityTypeConfiguration<Parent>
{
public ParentTypeConfiguration()
{
this.ToTable("Parents");
this.HasKey(c => c.ParentId);
this.HasMany(c => c.Children)
.WithOptional()
.HasForeignKey(p => p.ParentId)
.WillCascadeOnDelete(true);
}
}
然后我准备好了。到目前为止,一切都很好。
我创建了一个如下所示的测试,以查看我做的一切都很好......
[TestMethod]
public void RemoveParentEntity()
{
var parent = new Parent() { ParentName = "name" };
parent.Children = new Collection<Child>();
parent.Children.Add(new Child() { ChildName = "child1" });
parent.Children.Add(new Child() { ChildName = "child2" });
var unitOfWork = new MyUnitOfWork();
var repo = new ParentRepository(unitOfWork);
var count = repo.GetAll().Count();
repo.Add(parent);
repo.UnitOfWork.Commit();
//unitOfWork = new MyUnitOfWork();
//repo = new ParentRepository(unitOfWork);
repo.Remove(cadenaAprobacion);
repo.UnitOfWork.Commit();
var result = repo.GetAll().Count();
Assert.AreEqual(count, result);
}
这个测试失败了,说:
操作失败:无法更改关系,因为一个或多个外键属性不可为空。当对关系进行更改时,相关的外键属性将设置为空值。如果外键不支持空值,则必须定义新关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。
所以我用谷歌搜索/搜索了这个,我看到我应该让我的依赖属性成为可选的,因为子对象正在更新。所以我在实体中做到了,TypeConfiguration
并且我得到了一个DbUpdateException
典型的错误,我无法更新子对象等。
所以现在我很困惑。为了修复测试,我知道我可以做两件事:
在移除父对象之前移除子对象。这将在数据库中进行多项操作,这不是我想要的。
创建一个新的上下文,获取父实体并移除该实体。这将工作得很好,这些是之前在测试中注释的行。
我的问题是,当您在上下文中有子集合并且想要在 EF 中使用级联删除选项时,正确的做法是什么?如何在不对数据库进行操作的情况下从上下文中删除对象?
我确定我有一个概念问题,我希望有人指出它。所以我从错误中吸取教训:)