Entity Framework 命令拦截更改上下文连接字符串
Entity Framework Command Intercept change context connection string
目标:
当主数据库无法访问/关闭时回退到备份数据库。
当前实施:
检测到问题时,使用 class 实施 IDbCommandInterceptor 将连接字符串更改为后备服务器。
- 在拦截的上下文中关闭连接。
- 更改连接字符串。
- 打开连接。
这适用于 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 成员对于完整解决方案很有用。
目标:
当主数据库无法访问/关闭时回退到备份数据库。
当前实施:
检测到问题时,使用 class 实施 IDbCommandInterceptor 将连接字符串更改为后备服务器。
- 在拦截的上下文中关闭连接。
- 更改连接字符串。
- 打开连接。
这适用于 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 成员对于完整解决方案很有用。