【问题标题】:Soft delete with cascade deletion doesn't work as expected级联删除的软删除无法按预期工作
【发布时间】:2020-06-03 17:30:40
【问题描述】:

我在单元测试中使用 EF Core 和 SQLite。给定以下一对一实体:

public class Entity1 : FullAuditedEntity<int>
{
    public Entity2 Entity2 { get; set; }

    public string Name { get; set; }
}


public class Entity2 : FullAuditedEntity<int>
{
    public string Name { get; set; }       

    [ForeignKey("Entity1Id")]
    public Entity1 Entity1 { get; set; }
    public int Entity1Id { get; set; }
}

DbContext 类有如下代码:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    ...

    modelBuilder.Entity<Entity1>().HasOne(t => t.Entity2)
                                  .WithOne(t1 => t1.Entity1)
                                  .OnDelete(DeleteBehavior.Cascade);

    ...
}

我有一个测试方法:

[Fact]
public async Task Should_Create_And_Then_Delete_Single_Entity1()
{
    var entity1Service = Resolve<Entity1Service>();
    var entity1Repo = Resolve<IRepository<Entity1>>();
    var entity2Repo = Resolve<IRepository<Entity2>>();
    var entity1 = new entity1 { Name = "ent1" };

    entity2Repo.Count().ShouldBe(0);

    // entity2 created also, see assert below
    var created = await entity1Service.CreateEntity1Async(entity1).ConfigureAwait(false);
    created.Id.ShouldBe(1);
    created.Name.ShouldBe("net1");

    entity1Repo.Count().ShouldBe(1);
    entity2Repo.Count().ShouldBe(1);

    var ent = await entity1Service.GetEntity1Async(created.Id).ConfigureAwait(false);
    ent.ShouldNotBeNull();
    ent.Entity2.ShouldNotBeNull();

    await entity1Service.DeleteEntity1Async(ent.Id).ConfigureAwait(false);

    entity1Repo.Count().ShouldBe(0);
    entity2Repo.Count().ShouldBe(0);
}

问题是最后一行代码,"entity2Repo.Count().ShouldBe(0);"断言坏了,它实际上是1而不是0,IsDeleted(软删除)是false,但我希望它是true。

我做错了什么?

提前致谢。

【问题讨论】:

    标签: c# entity-framework-core cascade aspnetboilerplate soft-delete


    【解决方案1】:

    您需要自己级联软删除。
    请参阅已关闭 PR aspnetboilerplate/aspnetboilerplate#3559 中的基本原理。

    您可以通过定义 event handler 来做到这一点:

    public class Entity1DeletingCascader : IEventHandler<EntityDeletingEventData<Entity1>>, ITransientDependency
    {
        private readonly IRepository<Entity2> _entity2Repository;
    
        public Entity1DeletingCascader(IRepository<Entity2> entity2Repository)
        {
            _entity2Repository = entity2Repository;
        }
    
        [UnitOfWork]
        public virtual void HandleEvent(EntityDeletingEventData<Entity1> eventData)
        {
            var entity1 = eventData.Entity;
            _entity2Repository.Delete(e2 => e2.Entity1Id == entity1.Id);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-06
      • 1970-01-01
      • 2010-10-05
      • 2019-05-15
      • 2018-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多