我有一些嵌套的实体,当我软删除记录时,我想要自动删除记录的子记录(就像硬删除)。我该怎么做?最好的方法是什么?
class Base
{
bool isDeleted { set; get; }
}
class A : Base
{
//Collection of B
}
class B : Base
{
//Collection of C
}
class C : Base
{
//Collection of D
}
....例如:
表A:
Id ForeignKey(B Id) isDeleted
-------------------------------------
1 1 false表B:
Id ForeignKey(C Id) isDeleted
-------------------------------------
1 1 false
1 2 false
1 3 false表C:
Id ForeignKey(D Id) isDeleted
-------------------------------------
1 1 false
1 2 false
2 3 false
2 4 false
3 5 false
3 6 false代码:
public void SoftDeleteA()
{
//A.isDeleted = true;
//???How to soft-delete related records in B,C,D ,...
//SaveChanges();
}现在,当我从A中软删除行时,B和C的所有行也必须被软删除。
发布于 2020-11-30 19:03:53
没有用实体框架自动实现这一目标的方法。软删除只是一个术语,它并不实际删除记录,而是只更新单个列值,因此没有相关实体受此影响。但是,您可以使用实体框架或SQL触发器来完成此操作。由于您希望这种情况自动发生,所以在表A上创建一个更新触发器,并从更新的记录中在相关表中设置isDeleted。
与触发有关的条款:
https://www.tutorialgateway.org/after-update-triggers-in-sql-server/
https://www.sqlshack.com/triggers-in-sql-server/
使用实体框架,您需要先将父和所有子对象一起获取,然后单独修改它们并保存到数据库中。
示例:
public A FetchA()
{
return _context.A
.Include(a=>a.CollectionB)
.ThenInclude(b=>b.CollectionC)
.FirstOrDefaultAsync();
}
public void SoftDeleteA()
{
var a = FetchA();
if(a !=null)
{
a.isDeleted = true;
// loop through all related records and update them
if(a.CollectionB?.Any()== true)
{
foreach(var itemB in a.CollectionB)
{
itemB.isDeleted = true;
// loop through all related records and update them
if(itemB.CollectionC?.Any()== true)
{
foreach(var itemC in itemB.CollectionC)
{
itemC.isDeleted = true;
}
}
}
}
// save changes at last
_context.Update(a);
await _context.SaveChangesAsync() ;
}
}或者,如果您可以选择使用SQL,只需运行原始sql,这比使用EF快得多。
示例:
update b
set isDeleted = a.isDeleted
from B b
inner join A a on b.ID = a.ID发布于 2021-10-16 15:47:46
我用的是类似递归函数的东西;
class Base
{
public virtual bool IsDeleted { get; set; }
public virtual void DeleteMethod(int modifiedBy)
{
IsDeleted = true;
ModifiedMethod(modifiedBy);
}
}
class A : Base
{
//Collection of B
public override void DeleteMethod(int modifiedBy)
{
B.ForEach(oe => oe.DeleteMethod(modifiedBy));
base.DeleteMethod(modifiedBy);
}
}
class B : Base
{
//Collection of C
public override void DeleteMethod(int modifiedBy)
{
C.ForEach(oe => oe.DeleteMethod(modifiedBy));
base.DeleteMethod(modifiedBy);
}
}
class C : Base
{
//Collection of D
public override void DeleteMethod(int modifiedBy)
{
D.ForEach(oe => oe.DeleteMethod(modifiedBy));
base.DeleteMethod(modifiedBy);
}
}当调用一些{ParentClass}.DeleteMethod(),时,它对子类的开始操作。同样的事情,上面的答案,但涵盖所有继承的类,不需要写循环再次每个方法。
public async Task SoftDeleteAsync()
{
..
A.DeleteMethod(userid);
await context.SaveChangesAsync();
}https://stackoverflow.com/questions/65078681
复制相似问题