entity-framework - 使用 EF6,如何全局设置事务隔离级别等连接属性?
问题描述
使用 Entity Framework 6,如何为 EF 打开的每个连接设置连接属性?例如,如果我想覆盖默认的事务隔离级别。某些属性(例如事务隔离级别)无法使用连接字符串进行配置。
解决方案
在找到可行的解决方案之前,我尝试了几种不起作用的方法。没用的是:
失败#1:在DbContext
我调用的工厂方法中DbContext.Database.ExecuteSql
设置连接属性。这失败了,因为 EF 在用于其他调用之前正在重置连接。
失败 #2:使用或覆盖DbContext.SaveChanges
并DbContext.SaveChangesAsync
以指定的隔离级别将保存包装在事务中。这适用于保存更改,特别是隔离级别,但对查询或非隔离级别连接设置没有帮助。TransactionScope
DbContext.Database.BeginTransaction
失败#3:添加IDbTransactionInterceptor
和实现IsolationLevelGetting
,IsolationLevelGot
但是当您查询 EF 代码外部的事务隔离级别时,这些似乎只能更改返回的隔离级别。EF 代码在创建事务时不使用它。
成功:
实现一个IDbConnectionInterceptor
,实现Opened
,我在打开的连接上执行命令,在这种情况下设置事务隔离级别。这影响了 EF 执行的每个命令,并通过使用 SQL Profiler 确认。
脚步:
创建一个实现System.Data.Entity.Infrastructure.Interception.IDbConnectionInterceptor
public class ConnectionIsolationLevelInterceptor: IDbConnectionInterceptor
{
// Have empty implementations for all unused IDbConnectionInterceptor methods
public void BeganTransaction(DbConnection connection, BeginTransactionInterceptionContext interceptionContext)
{
}
...
... all other unused methods
...
public void Opened(DbConnection connection, DbConnectionInterceptionContext interceptionContext)
{
using (DbCommand command = connection.CreateCommand())
{
command.CommandText = "SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED";
command.ExecuteNonQuery();
}
}
}
在应用程序初始化代码中,添加拦截器:
DbInterception.Add(new ConnectionIsolationLevelInterceptor());
旁注:有许多不同的拦截器。参考EF 6 源代码是理解它们的最佳方式。静态方法是查找不同类型拦截器的DbInterception.Add
良好起点。Find All References on different dispatcher 方法显示了拦截器的使用位置。
推荐阅读
- docker - 詹金斯似乎在容器内运行
- c++ - 将一组类转换为类模板并避免构造函数歧义
- javascript - 如何将存储在java数组中的数据用于javascript?
- android - FirebaseRemoteConfigFetchException
- javascript - Async/await 在继续之前不会等待数据库查询
- visual-studio - Xamarin Android - 每次在调试模式下重新安装应用程序
- sql - 优化多列Null检查方式
- node.js - 表格没有更新
- c++ - 如果我们知道加密数据和密钥,是否有可能找出初始化向量
- c# - 启用 Exchange 缓存模式后,Outlook 中未显示搜索文件夹