EF Core - 编排 SavingChanges 和 SaveChanges 拦截器/事件以在保存更改后跟踪修改的实体

问题描述 投票:0回答:1

TLDR:我们如何编排 SavingChanges 和 SaveChanges 拦截器/事件,以在保存更改以进行后处理后跟踪修改的实体?

我们有一个带有 .NET 7、EFCore、SQL Server 和多租户方法的 REST API。我们有一个新的需求:实体保存在租户的 DBContext 中后,我们需要对它们进行后处理。他们全部。我知道这需要在 SaveChanges 完成后完成,并且每次在服务层中调用 saveChanges 时我们都可以简单地将实体排入队列,但不幸的是我们有遗留代码,并且需要在许多地方触发入队。我们希望在一个集中的地方做到这一点,因此我们考虑使用三种不同的方法:

  • 重写 DBContext 中的 SaveChanges 方法
  • SavingChanges / SaveChanges 事件
  • SavingChanges / SaveChanges 拦截器

我们已经覆盖了 SaveChanges,以便该选项处于打开状态。我们的问题是,我们在运行时创建指向不同数据库的上下文,因为我们有一个多租户软件,我们需要能够做到这一点,所以我们有一个用于创建 DbContext 的工厂,并且在 DbContext 构造函数中注入太多东西会增加工厂的复杂性。因此,覆盖 SaveChanges 是可能的,但很棘手。

这三种解决方案主要是相同的:在 SaveChanges 之前我们获取创建/修改的实体,在执行 SaveChanges 后我们将它们排入队列。通过重写 SaveChanges,这相当简单:我们获取更改的实体,并在执行 SaveChanges 后排队,但对于拦截器/事件,这很困难,因为没有线性执行,我们有两个不同的触发器(SavingChanges 和 SavedChanges)。一个具有包含所有跟踪更改的 DbContext,另一个具有保存更改后 DBContext 的新状态:无跟踪更改。所以,我的问题是:

我们如何编排 SavingChanges 和 SaveChanges 拦截器/事件来跟踪更改并能够在保存更改后将项目排入队列?拦截器是否以某种方式作为单例工作,因此跟踪修改的实体需要做更多工作,或者它们是否被实例化为瞬态/作用域并且很容易跟踪每个请求中的更改?

c# .net entity-framework interceptor
1个回答
0
投票

一种可能性是在

SaveChangesInterceptor
中使用字典或并发字典。键可以是
DbContext
的 ID,值可以是
SavingChanges
方法中检测到的跟踪实体列表。这种方法允许您跟踪实体之前的状态。此外,还需要重写其他方法,例如处理失败的方法,以清理字典并避免内存消耗问题。

© www.soinside.com 2019 - 2024. All rights reserved.