实体框架加入 NOLOCK

Posted

技术标签:

【中文标题】实体框架加入 NOLOCK【英文标题】:Entity Framework Joins with NOLOCK 【发布时间】:2016-07-27 17:00:49 【问题描述】:

我正在使用 Entity Framework 将 SQL 函数转换为 C#,并且我正在转换的函数对正在连接的每个表(其中 10 个)使用 NOLOCK 提示。

因此,我决定将整个事务的IsolationLevel 设置为ReadUncommitted。目前,我正在像这样进行内部连接。

from a in context.table1.ToList()
join b in context.table2.ToList on a.Id equals b.Id

以此类推

例如声明列表

IEnumerable<table1> Table1 = new List<table1>();

然后在我开始查询之前使用上下文填充它们会在这些表中产生不同的结果吗?即Table1 是否与context.table1.ToList() 相同?如果是这样,我应该采用哪种实现方式?

【问题讨论】:

【参考方案1】:
from a in context.table1.ToList()
join b in context.table2.ToList on a.Id equals b.Id

该语句会将 table1 中的所有项目具体化到内存中,将 table2 中的所有项目具体化到内存中,然后连接到内存中以进行其余的查询。除非您根本不关心性能,否则不要这样做。而是删除 ToList 调用并像这样加入。

from a in context.table1
join b in context.table2 on a.Id equals b.Id

这将在 sql server 中产生一个连接,现在您可以在 Linq 中继续查询的其余部分。然后,只要您开始迭代结果或使用扩展方法 ToList、ToArray、AsEnumerable 或检索单个项目的其他方法之一,如 Single 或 First 等,查询就会从数据库中实现结果(此处也隐含了异步版本)。


其次,我不建议使用 NOLOCK,否则可能会弹出意外的结果,除非您知道不正确的数据并不是什么大问题,例如可能显示没有对这些数据做出决定的易失性数据。现在,如果这不打扰您并且您仍想使用 NOLOCK 的等价物,那么围绕您的 EF 调用创建一个新事务。

using (new TransactionScope(TransactionScopeOption.Required, new TransactionOptions  IsolationLevel = IsolationLevel.ReadUncommitted )) 

    using (var context = new MyDbContext()) 
     
        var result = from a in context.table1
            join b in context.table2 on a.Id equals b.Id
            // rest of your linq query here.

    

【讨论】:

我不知道我是否会使用它,但有没有办法在每张桌子上做到这一点? 没有开箱即用,它需要在您的 DbContext 中添加一些额外的逻辑来更改发送到服务器的查询。您可以创建一个带有 NOLOCK 提示的 VIEW 并将该视图映射到 IF 中的实体,然后从您的 c# 代码中抽象出 NOLOCK 提示。 我正在为我的工作转换这些,到目前为止我转换的 SP 要容易得多。我的直觉告诉我不要质疑 NOLOCK,因为它现在超出了我的工资等级。感谢您提供摆脱 ToList() 的提示。 @C-Scholl20 - 很高兴它有帮助。如果您认为答案是正确的,请不要忘记使用复选框标记答案。

以上是关于实体框架加入 NOLOCK的主要内容,如果未能解决你的问题,请参考以下文章

获取实体框架 6 在其下面的 SELECT 语句中使用 NOLOCK

实体框架加入 ms-access

加入并包含在实体框架中

实体框架代码优先自加入,'多重性在角色中无效'

加入前包含不起作用实体框架6

实体框架加入3个表