从本地集合中删除项目而不删除
Posted
技术标签:
【中文标题】从本地集合中删除项目而不删除【英文标题】: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
方法,这会导致数据库更新。
【参考方案1】:
我认为您将执行硬删除,因为您在调用RemoveBaz
方法之后调用了Context.Savechange
方法。
在RemoveBaz
之后,你的List<Baz>
删除了Baz
,然后你执行SavaChange
,这将执行硬删除。
您应该在Savechange
之后编写您的RemoveBaz
方法。
像这样更改您的RemoveBaz
:
public void RemoveBaz(Baz baz)
_bazes.Remove(baz);
那么删除顺序应该是baz.Delete()
=>SaveChange
=>bar.RemoveBaz(baz)
这是你的问题测试:
这是我的解决方案测试:
【讨论】:
你读过这个问题吗?他已经做到了这一点。 如果我的回答对你有用,可以标记为答案,对以后遇到同样问题的人有帮助。以上是关于从本地集合中删除项目而不删除的主要内容,如果未能解决你的问题,请参考以下文章