用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
明确写了(如我上面的ToListNoLock
) ToListNoLock
。 所以,例如:
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"); }