NOLOCK与Linq to SQL

时间:2009-08-03 05:47:00

标签: linq-to-sql

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

5 个答案:

答案 0 :(得分:82)

是的,所以这是条目from my blog

  

NOLOCK提示基本上是   与包装查询相同   “隔离级别”的事务   设置为“未提交读”。它的意思是   查询不关心是否有东西   正在被写入   它正在读取的行 - 它会   读取“脏”数据并将其返回   作为结果集的一部分。

     

原来你可以做到全部   “读未提交”交易的事情   使用旧的System.Transactions   .NET 2.0中引入的命名空间。   这是一些示例代码:

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

所以我正在创建一个新的TransactionScope   对象并告诉它使用   读取未提交的隔离级别。该   现在在“使用”语句中查询   就好像它的所有表都在阅读一样   与NOLOCK提示。

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

InfoQ: Implementing NOLOCK with LINQ to SQL and LINQ to Entities

Matt Hamilton - LINQ to SQL and NOLOCK Hints : Mad Props!

Scott Hanselman's Computer Zen - Getting LINQ to SQL and LINQ to ...

答案 1 :(得分:19)

进一步向国王LinqPad My Extensions addition

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);
    }   
}

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

somequery.NoLock((x)=>x.Count()).Dump();

将使用NOLOCK评估查询。

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

答案 2 :(得分:11)

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

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

  // Your SQL query
}

答案 3 :(得分: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();
    }   
}

然后你可以把它称为:

MyTable.Where(t => t.Title = "Blah").Dump2();

答案 4 :(得分:2)

就我而言,实体框架5(基于@Soppus答案):

private FoobarEntities db = new FoobarEntities();
public FoobarController()
{
    db.Database.ExecuteSqlCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED");
}