是否有可能使Linq2Sql在其SQL中发出NOLOCK?如果是这样,怎么办?
Answers:
是的,所以这是我的博客中的条目:
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 }
因此,我正在创建一个新的TransactionScope对象,并告诉它使用未提交的隔离级别。现在,“ using”语句中的查询的行为就像其所有表都在读取带有NOLOCK提示的内容一样。
这是Google搜索“ linq sql nolock”的第一个结果:
InfoQ:使用LINQ to SQL和LINQ to Entities实现NOLOCK
除了King的LinqPadMy 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
对未NoLock
明确为其编写的任何评估查询执行“ a ”操作(ToListNoLock
如上文所述)。因此,例如:
somequery.NoLock((x)=>x.Count()).Dump();
将使用评估查询NOLOCK
。
请注意,您必须确保正在评估查询。例如.NoLock((x)=>x.Distinct()).Count().Dump()
不会做任何与有用的区别.Distinct().Count().Dump()
。
这是与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();
以我为例,实体框架5(基于@Soppus答案):
private FoobarEntities db = new FoobarEntities();
public FoobarController()
{
db.Database.ExecuteSqlCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED");
}