0

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

因此,我决定为整个事务设置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>();

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

4

1 回答 1

4
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.

    }
}
于 2016-07-27T17:08:13.920 回答