如何保留 Db Context 和 Restore 的更改跟踪信息?

How to Persist change tracking info of Db Context & Restore?

We have to detect changes inside DB Context and schedule the DB update at a later date.

如何将 change tracker info of Db Context 保存到临时数据库中,以便日后可以将它们恢复到另一个 DbContext 实例中。

So merely .SaveChanges on newly built Db Context instance should commit the pending changes.

也许您需要做的就是拥有一个与您的主(远程)数据库具有相同结构的本地临时数据库;然后将 SaveChanges 保存到本地数据库而不是主数据库中。

要将 SaveChanges 指向本地数据库而不是主数据库,您只需在创建 DbContext 时使用不同的连接字符串即可。 (虽然已经有一些关于能够更改 DbContext 上的连接的讨论,但目前尚未实现,请参阅 https://github.com/aspnet/EntityFrameworkCore/issues/8494。)。

所以...假设您的更改在 "main" DbContext 中,然后您为本地数据库创建第二个 DbContext,然后只需从 'main' DbContext.ChangeTracker 到 'local' DbContext.ChangeTracker。您可以通过遍历 ChangeTracker 条目和: 克隆实体(构造一个实体并使用 PropertyInfo.SetValue 从 EntityEntry.OriginalValues 复制所有值);将实体附加到 'local' DbContext;然后应用更改(使用 EntityEntry.CurrentValues 获取当前值,测试 !EqualityComparer.Default.Equals,如果不相等,则再次使用 PropertyInfo.SetValue 应用当前值)。

如果你只需要一个浅拷贝,那是相当简单的;如果您需要深拷贝,那么您还需要浏览模型中的关系。

替代所有这些,一种不同的方法是始终将所有内容保存到本地数据库,然后有一个单独的过程,例如将值复制到主数据库的批处理过程。作为一般性评论,无论您如何执行此操作,您都需要处理在将本地值发送到主数据库时可能出现的任何并发冲突。

史蒂夫

P.S。也可能值得尝试使用 DbContext.Database 看看是否可以重定向连接——如果您愿意走出 'supported' API。

我可以想到两个解决方案:

  1. 向 table 添加批准的字段并根据值过滤输出(使用视图只读取批准的项目),删除 non-approved 记录。 (适用于大多数请求将被批准且不需要保留历史数据的情况)。

  2. 复制服务器上现有的 table(仅结构),这允许重用生成的 EF 类,称为 Requests。批准后,使用 SQL 查询将记录添加到主 table,并从请求 table 中删除该行。如果请求被拒绝,您可以将其添加到 denied table 并给出拒绝的原因。

这些方法的优点:

  1. 由于所有操作都发生在同一个数据库中,而不是在本地或不同的数据库中,因此原子事务是可能的,并且可以使用现有的 backup/recovery/availability 策略。

  2. (#2)可以创建历史记录以提供责任信息。