EF Core 2.0 TransactionScope 错误

4
我正在尝试在EntityFramework Core 2.0中的SELECT查询中使用TransactionScope。然而,我遇到了这个错误:"Enlisting in Ambient transactions is not supported." 我的想法是在执行SELECT查询时实现"NO LOCK"选项(我知道在这种情况下使用该选项不是一个好主意,但这是供应商的要求)。因此,我添加了一个扩展方法(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 Core 2.0 支持 TransactionScope ,但不确定为什么会出现此异常。您有任何想法吗?
2个回答

8

System.Transactions在EF Core中尚不支持。该问题已由#5595:启用对System.Transactions的支持跟踪,并且承诺将包含在下一个EF Core 2.1版本中。(更新:EF Core 2.1确实添加了System.Transactions的支持)。

在那之前,如果整个目的是使用带有ReadUncommitted的事务,则可以尝试使用显式EF Core IDbTransaction通过BeginTransaction(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;
    }
}

0
我找到了一个解决方法,不需要为每个查询使用事务范围。如果运行下面的代码,EF将为相同的服务器进程ID使用相同的事务隔离级别。由于在同一请求中Server Process ID不会改变,因此每个请求只需要调用一次即可。
this.Database.ExecuteSqlCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;");

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接