【问题标题】:Remove an item from a local collection without deleting从本地集合中删除项目而不删除
【发布时间】:2021-02-15 15:42:30
【问题描述】:

我有以下设置:

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 管理的:

在 Foo ->

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 集合中删除

【问题讨论】:

  • 就我个人而言,我不会打扰...但是您可以覆盖 SaveChanges / SaveChangesAsync 并运行保存前和保存后的方法,将删除转换为更新,然后分别从跟踪更改中删除。
  • 嗨@JGillardCCG,关于这个案例有什么更新吗?
  • 由于时间限制,我们选择硬删除 Baz
  • 在我看来,你硬删除的唯一原因是在本地集合中删除Baz后执行Savechange方法,这会导致数据库更新。

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


【解决方案1】:

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

RemoveBaz之后,你的List&lt;Baz&gt;删除了Baz,然后你执行SavaChange,这将执行硬删除。

您应该在Savechange 之后编写您的RemoveBaz 方法。

像这样更改您的RemoveBaz

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

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

这是你的问题测试:

这是我的解决方案测试:

【讨论】:

  • 你读过这个问题吗?他已经做到了这一点。
  • 如果我的回答对你有用,可以标记为答案,对以后遇到同样问题的人有帮助。
猜你喜欢
  • 2013-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多