带级联删除的软删除无法按预期工作
Soft delete with cascade deletion doesn't work as expected
我在单元测试中使用 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
class 有以下代码:
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
.
我做错了什么?
提前致谢。
您需要自己进行级联软删除。
请参阅已关闭 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);
}
}
我在单元测试中使用 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
class 有以下代码:
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
.
我做错了什么?
提前致谢。
您需要自己进行级联软删除。
请参阅已关闭 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);
}
}