[英]Soft delete nested entities in EF Core
我有一些嵌套实体,当我软删除该记录(如硬删除)时,我想自动软删除该记录的子项。 我怎样才能做到这一点? 最好的方法是什么?
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 的所有行也必须被软删除
实体框架没有自动的方法来实现这一点。 软删除只是一个术语,它实际上并没有删除记录,而只是更新单个列值,因此不会影响相关实体。 但是,您可以使用实体框架或 SQL 触发器来执行此操作。 由于您希望这自动发生,请在表 A 上创建一个更新触发器,并在更新记录的相关表中设置 isDeleted。
触发相关文章:
https://docs.microsoft.com/en-us/sql/t-sql/statements/create-trigger-transact-sql?view=sql-server-ver15
https://www.tutorialgateway.org/after-update-triggers-in-sql-server/
https://www.sqlshack.com/triggers-in-sql-server/
https://www.aspsnippets.com/Articles/Simple-Insert-Update-and-Delete-Triggers-in-SQL-Server-with-example.aspx
使用实体框架,您需要首先获取您的父级和所有子级,单独修改它们并保存到数据库。
例子:
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
我正在使用类似Recursive Functions的东西;
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();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.