Entity Framework Core - 使用 OData 执行 NOLOCK 查询

问题描述 投票:0回答:1

我正在尝试使用

NOLOCK
执行 EF Core 查询,有一篇文章演示了如何编写扩展方法,但它在 OData 查询中无法按预期工作。

这是链接: https://stackoverflow.com/a/63603655

query.ToListAsync
正在对表运行查询并尝试获取数百万条记录。而我正在尝试使用过滤器传递此查询

https://localhost:60484/odata/Users?$filter=userId eq 123&$expand=产品、订单

所以基本上,我试图从用户表中获取记录,其中

user id = 123
并且还想扩展产品和订单外键属性。

// Controller method
[HttpGet]
[EnableQuery]
public async Task<IQueryable<User>> Get()
{
    return await _repository.UserRepository.GetUserData();
}

// Repository base
public async Task<List<T>> FindAll() => await _dbContext.Set<T>().AsNoTracking().ToListWithNoLockAsync();

// Repository method
public async Task<IQueryable<User>> GetUserData()
{
    var data = await FindAll();
    return data.AsQueryable()
                .Include(a => a.Products)
                .Include(a => a.Orders);
}

// Extension method from the article
public static class EFCoreTransaction
{
    public static async Task<List<T>> ToListWithNoLockAsync<T>(
                                        this IQueryable<T> query,
                                        Expression<Func<T, bool>>? expression = null,
                                        CancellationToken cancellationToken = default)
    {
        List<T>? result = default;

        using (var scope = CreateTransaction())
        {
            if (expression != null)
            {
                query = query.Where(expression);
            }

            result = await query.ToListAsync(cancellationToken);

            scope.Complete();
        }

        return result!;
    }

    private static TransactionScope CreateTransaction()
    {
        return new TransactionScope(TransactionScopeOption.Required,
                                    new TransactionOptions()
                                    {
                                        IsolationLevel = IsolationLevel.ReadUncommitted
                                    },
                                    TransactionScopeAsyncFlowOption.Enabled);
    }
}
asp.net-core entity-framework-core odata nolock
1个回答
0
投票

我找到了一种方法来做到这一点。最终,我可以保持存储库类不变,只创建本文中提到的扩展类。 然后,在控制器中,我使用 ODataQueryOptions 进行了这些更改。由于 Iqueryable 实际上并不执行数据库查询,因此它将获取记录,然后在未提交读取的情况下应用 ToList() 。任何专家意见都会受到赞赏。我通过检查日志和 SQL 探查器对此进行了测试。生成的查询正在事务范围内运行。

[HttpGet]
[EnableQuery]
public async Task<IActionResult> Get(ODataQueryOptions<User> options)
{
    IQueryable<User>? tempQuery = _repository.LeasedVendorsRepository.GetUserData();
    IQueryable<User> result = tempQuery;
    if (options.SelectExpand != null)
    {
        if (options.Filter != null)
        {
            tempQuery = options.Filter.ApplyTo(tempQuery, new ODataQuerySettings()) as IQueryable<User>;
        }
        result = (await tempQuery!.ToListWithNoLockAsync()).AsQueryable();
        Request.ODataFeature().SelectExpandClause = options.SelectExpand.SelectExpandClause;
    }
    return Ok(result);
}
© www.soinside.com 2019 - 2024. All rights reserved.