首页 > 解决方案 > 从本地集合中删除项目而不删除

问题描述

我有以下设置:

public class Foo
{
    public int FooId { get; private set; }
}

public class Bar
{
    public int FooId { get; private set; }
    public Foo Foo { get; private set; }

    private readonly List<Baz> _bazes= new List<Baz>();
    public IReadOnlyCollection<Baz> Bazes => _bazes.AsReadOnly();

    public Baz AddBaz(Baz baz)
    {
        _bazes.Add(baz);
    }

    public void RemoveBaz(Baz baz)
    {
        baz.Delete();
        _bazes.Remove(baz);
    }
}

public class Baz
{
    public int BazId { get; private set; }

    public int FooId { get; private set; }
    public Foo Foo { get; private set; }

    public int QuxId { get; private set; }
    public Qux Qux { get; private set; }

    public DateTime? DateDeleted { get; private set; }

    public void Delete()
    {
        DateDelete = DateTime.UtcNow;
    }
}

public class Qux
{
    public int QuxId { get; private set; }
}

这都是通过 EF Core 管理的:

安富->

builder.HasKey(k => k.FooId);
builder.Property(p => p.FooId).ValueGeneratedOnAdd();

在酒吧 ->

builder.HasKey(k => k.FooId);
builder.Property(p => p.FooId).ValueGenerateNever();

builder.HasMany(hm => hm.Baz).WithOne().HasForeignKey(fk => fk.FooId);

在巴兹 ->

builder.HasQueryFilter(qf => !qf.DateDeleted.HasValue);

builder.HasKey(k => k.BazId);
builder.Property(p => p.BazId).ValueGeneratedOnAdd();

builder.HasOne(ho => ho.FooId).WithMany().HasForeignKey(fk => fk.FooId);
builder.HasOne(ho => ho.QuxId).WithMany().HasForeignKey(fk => fk.QuxId);

在 Qux ->

builder.HasKey(k => k.QuxId);
builder.Property(p => p.QuxId).ValueGenerateOnAdd();

除了尝试删除 Baz 时,所有这些都完全按预期工作。因为我只想软删除,所以我调用 Baz.Delete(),但我还需要将它从 Bar._bazes 中删除,否则我的单元测试仍然显示它在对象上。这样做的问题是它试图从数据库中硬删除 Baz,这是我不想要的,我收到了一个错误:

“实体类型 'Foo' 和 'Baz' 之间的关联已被切断,但该关系要么被标记为‘必需’,要么是隐式必需的,因为外键不可为空。如果在需要时应删除依赖/子实体关系被切断,然后设置关系以使用级联删除。考虑使用“DbContextOptionsBuilder.EnableSensitiveDataLogging”来查看键值。”

有没有办法解决这个问题?在理想情况下,Baz 应该只软删除,但仍应从 Bar 上的 baze 集合中删除

标签: c#asp.net-core.net-coreentity-framework-core

解决方案


我认为您将执行硬删除,因为您在调用该Context.Savechange方法后调用该RemoveBaz方法。

之后RemoveBaz,您的List<Baz>已删除Baz,然后您执行SavaChange,这将执行硬删除。

你应该RemoveBazSavechange.

像这样改变你RemoveBaz

public void RemoveBaz(Baz baz)
    {
        _bazes.Remove(baz);
    }

那么删除的顺序应该是baz.Delete()=> SaveChange=>bar.RemoveBaz(baz)

这是您的问题测试:

在此处输入图像描述

这是我的解决方案测试: 在此处输入图像描述


推荐阅读