首页 > 解决方案 > 仅对 DbContext 中的一个查询使用选项 IsolationLevel.ReadUncommited

问题描述

在 .NET Core 项目中,我使用的是 EntityFramework,并且在我的类存储库中注入了一个 DbContext (shopContext)。我有下一个查询:

var res = shopContext.Orders.Where(x => x.Status == 1).Sum(p => p.Total);

有时,Orders 表正在执行维护任务并且该表被锁定。对于此查询,我迫不及待地执行维护任务,我需要使用IsolationLevel.ReadUncommited事务中的选项访问表:

using (var transaction = mutuaContext.Database.BeginTransaction(IsolationLevel.ReadUncommitted))
{
    var res = shopContext.Orders.Where(x => x.Status == 1).Sum(p => p.Total);
}

问题是我只希望上下文在这些查询中使用此 IsolationLevel 配置执行查询,但尽管表已锁定,但下一个查询继续执行。

为什么以下查询不等待表被解锁?

我的代码示例:

using (var transaction = mutuaContext.Database.BeginTransaction(IsolationLevel.ReadUncommitted))
{
    var res = shopContext.Orders.Where(x => x.Status == 1).Sum(p => p.Total); // this code would be executed
}

var total = shopContext.Orders.Where(x => x.Status == 0).Sum(p => p.Total); // this code would NOT be executed but is executed

我不明白上下文如何获取事务配置。我希望有人向我解释。

transaction.Commit()我在第一次查询后尝试调用,但仍然无法正常工作。

标签: c#.netsql-serverentity-frameworklinq

解决方案


您可以使用原始 SQL 查询(EF6 也有类似的SqlQuery()方法)并指定with (nolock)表提示。像这样的东西:

var res = shopContext.Orders.FromSqlRaw("select sum(Total) from dbo.Orders with (nolock) where Status = 1").ToList();

但是,一旦您将其部署到生产环境中并将您的代码置于适当的并发负载下,您很可能不会喜欢这种结果。

UPD:对于 EF Core 2.2,语法有点不同:

var res = shopContext.Orders.FromSql("select * from Orders with(nolock)")
  .Where(x => x.Status == 1).Sum(p => p.Total);

推荐阅读