NOLOCK与Linq to SQL

Sco*_*zie 69 linq-to-sql

是否有可能让Linq2Sql在其SQL中发出NOLOCK?如果是这样,怎么样?

Mat*_*ton 85

是的,所以这是我博客的条目:

NOLOCK提示与在"隔离级别"设置为"未提交读取"的事务中包装查询基本相同.这意味着查询不关心是否正在写入正在读取的行的过程中 - 它将读取"脏"数据并将其作为结果集的一部分返回.

事实证明,您可以使用.NET 2.0中引入的旧System.Transactions命名空间来执行整个"读取未提交"事务.这是一些示例代码:

using (var txn = new TransactionScope(
    TransactionScopeOption.Required, 
    new TransactionOptions
    {
        IsolationLevel = IsolationLevel.ReadUncommitted
    }
))
{
    // Your LINQ to SQL query goes here
}
Run Code Online (Sandbox Code Playgroud)

所以我正在创建一个新的TransactionScope对象并告诉它使用read-uncommitted隔离级别.现在,"using"语句中的查询就好像所有表都在使用NOLOCK提示进行读取一样.

以下是Google搜索"linq sql nolock"的第一个结果:

InfoQ:使用LINQ to SQL和LINQ to Entities实现NOLOCK

Matt Hamilton - LINQ to SQL和NOLOCK提示:Mad Props!

Scott Hanselman的计算机Zen - 获取LINQ to SQL和LINQ to ...

  • 必须与Matt就内容窃取事件进行协商.马特花时间在他的博客上写这篇文章.现在SOF正在增加流量 (7认同)
  • 如果我想完全正确,这些选项中没有一个实际上在SQL本身中"发出NOLOCK" - 它们使用事务的隔离设置.同样的,但技术上不是问题. (6认同)
  • 你不能在博客上投票和投票,所以没有办法审查那里的质量.我认为通过归因将短片段复制到SO是正确的方法. (4认同)
  • 从您的博客复制文本,以便没有人必须点击链接才能得到答案. (3认同)
  • @Matt:这就是重点!创建一个规范的来源!请参阅:http://meta.stackexchange.com/questions/8724/how-to-deal-with-google-questions/8729#8729 (2认同)

Mar*_*urd 22

继进入King的LinqPad My Extensions之外:

public static IQueryable<T> DumpNoLock<T>(this IQueryable<T> query)
{
    using (var txn = GetNewReadUncommittedScope())
    {
        return query.Dump();
    }   
}

public static System.Transactions.TransactionScope GetNewReadUncommittedScope()
{
    return new System.Transactions.TransactionScope(
        System.Transactions.TransactionScopeOption.RequiresNew,
        new System.Transactions.TransactionOptions
        {
            IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted
        });
}
public static IQueryable<T> DumpNoLock<T>(this IQueryable<T> query, string description)
{
    using (var txn = GetNewReadUncommittedScope())
    {
        return query.Dump(description);
    }   
}

public static List<T> ToListNoLock<T>(this IQueryable<T> query)
{
    using (var txn = GetNewReadUncommittedScope())
    {
        return query.ToList();
    }   
}

public static U NoLock<T,U>(this IQueryable<T> query, Func<IQueryable<T>,U> expr)
{
    using (var txn = GetNewReadUncommittedScope())
    {
        return expr(query);
    }   
}
Run Code Online (Sandbox Code Playgroud)

最后一个意味着您可以NOLOCK对任何未NoLock明确编写的评估查询执行操作(就像我ToListNoLock上面提到的那样).所以,例如:

somequery.NoLock((x)=>x.Count()).Dump();
Run Code Online (Sandbox Code Playgroud)

将评估查询NOLOCK.

请注意,您必须确保评估查询.例如,.NoLock((x)=>x.Distinct()).Count().Dump()不会做任何有用的事情.Distinct().Count().Dump().


Sop*_*pus 11

一种简单的方法可能是在DataContext类上运行命令

using (var dataContext = new DataContext())
{
  dataContext.ExecuteCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED");

  // Your SQL query
}
Run Code Online (Sandbox Code Playgroud)


the*_*ing 8

这是一个与LINQPAD一起使用的扩展方法

    public static IQueryable<T> Dump2<T>(this IQueryable<T> query)
{
    using (var txn = new System.Transactions.TransactionScope(TransactionScopeOption.RequiresNew, 
        new TransactionOptions
        {       
            IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted
        }))
    {
        return query.Dump();
    }   
}
Run Code Online (Sandbox Code Playgroud)

然后你可以把它称为:

MyTable.Where(t => t.Title = "Blah").Dump2();
Run Code Online (Sandbox Code Playgroud)