Entity Framework 命令拦截更改上下文连接字符串

Entity Framework Command Intercept change context connection string

目标

当主数据库无法访问/关闭时回退到备份数据库。

当前实施

检测到问题时,使用 class 实施 IDbCommandInterceptor 将连接字符串更改为后备服务器。

  1. 在拦截的上下文中关闭连接。
  2. 更改连接字符串。
  3. 打开连接。

这适用于 ReaderExecuting,但不适用于 NonQueryExecuting。我可以看到与后备服务器的连接已打开并且看起来不错,但我在 context.SaveChanges():

期间得到以下信息

基础提供程序提交失败。

InnerException: 值不能为空。参数名称:连接

更新: 在进一步研究之后,我发现问题发生在由 SaveChanges() 创建的事务中。在上下文中关闭连接会导致事务对象在提交时抛出异常。我找不到更改此事务的连接或连接字符串的方法。使用 IDbTransactionInterceptor 在 ConnectionGetting() 中处理它并在上下文中创建新事务没有帮助,它仍然会继续尝试提交(可能是竞争条件,无论如何都不是这样做的好方法)。 ChangeDatabase() 似乎无法正常工作,因为连接应该连接到同一台服务器。

所以现在的问题是:有没有办法更改现有事务的连接/连接字符串?

堆栈跟踪:

at System.Data.Entity.Utilities.Check.NotNull[T](T value, String parameterName)
at System.Data.Entity.Infrastructure.Interception.DbTransactionInterceptionContext.WithConnection(DbConnection connection)
at System.Data.Entity.Infrastructure.Interception.DbTransactionDispatcher.Commit(DbTransaction transaction, DbInterceptionContext interceptionContext)
at System.Data.Entity.Core.EntityClient.EntityTransaction.Commit()

更改连接字符串的正确位置是在实现 IDbConnectionInterceptor 接口的 Opening() 中。这适用于简单的读取、写入和事务。 在处理单个 sql 命令行为时,实现 IDbCommandInterceptor 成员对于完整解决方案很有用。