1

我正在创建一个代码,我想在其中使用级联删除父对象及其所有子对象,以减少正在执行的删除操作的数量。

所以我有两个这样的实体

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典型的错误,我无法更新子对象等。

所以现在我很困惑。为了修复测试,我知道我可以做两件事:

  1. 在移除父对象之前移除子对象。这将在数​​据库中进行多项操作,这不是我想要的。

  2. 创建一个新的上下文,获取父实体并移除该实体。这将工作得很好,这些是之前在测试中注释的行。

我的问题是,当您在上下文中有子集合并且想要在 EF 中使用级联删除选项时,正确的做法是什么?如何在不对数据库进行操作的情况下从上下文中删除对象?

我确定我有一个概念问题,我希望有人指出它。所以我从错误中吸取教训:)

4

0 回答 0