用LINQ NOLOCK到SQL

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

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

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 } 

所以我创build一个新的TransactionScope对象,并告诉它使用一个读取未提交的隔离级别。 现在,“using”语句中的查询就好像其所有表都使用NOLOCK提示进行读取。

以下是Googlesearch“linq sql nolock”的第一个结果:

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

马特·汉密尔顿 – LINQ to SQL和NOLOCK提示:疯狂道具!

Scott Hanselman的计算机禅 – 获取LINQ to SQL和LINQ to …

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

最后一个意味着你可以做任何评估查询你没有一个NoLock明确写了(如我上面的ToListNoLockToListNoLock 。 所以,例如:

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

将使用NOLOCK评估查询。

请注意,您必须确保您正在评估查询。 例如.NoLock((x)=>x.Distinct()).Count().Dump()不会做与.Distinct().Count().Dump()不同的任何有用的操作。

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

 using (var dataContext = new DataContext()) { dataContext.ExecuteCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED"); // Your SQL query } 

这是一个与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(); 

在我的情况下,entity framework5(基于@Soppus答案):

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