EF核心2.0 TransactionScope错误

问题描述:

我想在EntityFramework核心2.0中的SELECT查询中使用TransactionScope。但是,我收到此错误:“不支持”加入环境事务。“EF核心2.0 TransactionScope错误

当我选择查询时,这个想法是实现“无锁定”选项(我知道有这个选项,但它是供应商的要求不是个好主意)。所以我添加的扩展方法(Entity Framework with NOLOCK

public static async Task<List<T>> ToListReadUncommittedAsync<T>(this IQueryable<T> query) 
{ 
    using (var scope = new TransactionScope(TransactionScopeOption.RequiresNew, 
     new TransactionOptions() 
     { 
      IsolationLevel = IsolationLevel.ReadUncommitted 
     }, TransactionScopeAsyncFlowOption.Enabled)) 
    { 
     var result = await query.ToListAsync(); 
     scope.Complete(); 
     return result; 
    } 
} 

而且我也已经设置忽略环境事务警告。

public static void AddEntityFramework(this IServiceCollection services, string connectionString) 
{ 
    services.AddDbContextPool<OptomateContext>(options => 
    { 
     options.UseSqlServer(connectionString); 
     options.ConfigureWarnings(x => x.Ignore(RelationalEventId.AmbientTransactionWarning)); 
    }); 
} 

和我有查询,如下面我的仓库

public async Task<Patient> GetPatient(Common.Resources.Patient patient) 
{ 
    var pat = await Dbset.Where(x => string.Equals(x.Surname,patient.Surname, 
    StringComparison.CurrentCultureIgnoreCase)).ToListReadUncommittedAsync();          

    return pat.FirstOrDefault(); 
} 

我明白,对.NET核心2.0支持的TransactionScope。但我不知道为什么我得到这个例外。

任何想法为什么会发生这种情况?

System.Transactions没有在EF核心的支持呢。该问题跟踪#5595: Enable support for System.Transactionsis committed to be included in the next EF Core release 2.1

在此之前,如果整点要使用与ReadUncommitted的交易,则可尝试使用明确的EF Core IDbTransactionBeginTransaction(DatabaseFacade, IsolationLevel)扩展方法。不幸的是它不能完全在您的当前自定义扩展方法封装等,并需要经过DbContext实例:

public static async Task<List<T>> ToListReadUncommittedAsync<T>(this IQueryable<T> query, DbContext context) 
{ 
    using (var transaction = await context.Database.BeginTransactionAsync(System.Data.IsolationLevel.ReadUncommitted))   { 
    { 
     var result = await query.ToListAsync(); 
     transaction.Commit(); 
     return result; 
    } 
} 

我发现,不使用事务范围为每个查询一个解决方法。如果您运行下面的代码,那么ef将对相同的服务器进程ID使用相同的事务隔离级别。由于服务器进程ID在同一请求中没有更改,因此每个请求只需要一次调用就足够了。

​​