Rei*_*ica 204
不,但您可以启动事务并将隔离级别设置为uncommited.这基本上与NOLOCK相同,但它不是基于每个表执行,而是针对事务范围内的所有内容执行此操作.
如果这听起来像你想要的那样,这就是你如何去做...
//declare the transaction options
var transactionOptions = new System.Transactions.TransactionOptions();
//set it to read uncommited
transactionOptions.IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted;
//create the transaction scope, passing our options in
using (var transactionScope = new System.Transactions.TransactionScope(
System.Transactions.TransactionScopeOption.Required,
transactionOptions)
)
//declare our context
using (var context = new MyEntityConnection())
{
//any reads we do here will also read uncomitted data
//...
//...
//don't forget to complete the transaction scope
transactionScope.Complete();
}
Run Code Online (Sandbox Code Playgroud)
Ale*_*dre 81
扩展方法可以使这更容易
public static List<T> ToListReadUncommitted<T>(this IQueryable<T> query)
{
using (var scope = new TransactionScope(
TransactionScopeOption.Required,
new TransactionOptions() {
IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted }))
{
List<T> toReturn = query.ToList();
scope.Complete();
return toReturn;
}
}
public static int CountReadUncommitted<T>(this IQueryable<T> query)
{
using (var scope = new TransactionScope(
TransactionScopeOption.Required,
new TransactionOptions() {
IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted }))
{
int toReturn = query.Count();
scope.Complete();
return toReturn;
}
}
Run Code Online (Sandbox Code Playgroud)
Fra*_*ain 26
如果你需要大量的东西,我们找到的最好的方法是每次实际启动一个事务管理器,那么在你通过运行这个简单的命令创建对象上下文之后,只需设置连接上的默认事务隔离级别:
this.context.ExecuteStoreCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;");
Run Code Online (Sandbox Code Playgroud)
http://msdn.microsoft.com/en-us/library/aa259216(v=sql.80).aspx
通过这种技术,我们能够创建一个简单的EF提供程序,为我们创建上下文,并且每次为我们的所有上下文实际运行此命令,以便我们始终处于"未提交读取"状态.
Yur*_*kiy 19
虽然我绝对同意使用Read Uncommitted事务隔离级别是最好的选择,但有些时候你被迫通过经理或客户端的请求使用NOLOCK提示并且没有理由反对这种接受.
使用Entity Framework 6,您可以像这样实现自己的DbCommandInterceptor:
public class NoLockInterceptor : DbCommandInterceptor
{
private static readonly Regex _tableAliasRegex =
new Regex(@"(?<tableAlias>AS \[Extent\d+\](?! WITH \(NOLOCK\)))",
RegexOptions.Multiline | RegexOptions.IgnoreCase);
[ThreadStatic]
public static bool SuppressNoLock;
public override void ScalarExecuting(DbCommand command,
DbCommandInterceptionContext<object> interceptionContext)
{
if (!SuppressNoLock)
{
command.CommandText =
_tableAliasRegex.Replace(command.CommandText, "${tableAlias} WITH (NOLOCK)");
}
}
public override void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
if (!SuppressNoLock)
{
command.CommandText =
_tableAliasRegex.Replace(command.CommandText, "${tableAlias} WITH (NOLOCK)");
}
}
}
Run Code Online (Sandbox Code Playgroud)
有了这个类,您可以在应用程序启动时应用它:
DbInterception.Add(new NoLockInterceptor());
Run Code Online (Sandbox Code Playgroud)
并有条件地关闭添加NOLOCK提示到当前线程的查询:
NoLockInterceptor.SuppressNoLock = true;
Run Code Online (Sandbox Code Playgroud)
第一个" ReadUncommitedTransactionScopeAttribute "
[Serializable]
public class ReadUncommitedTransactionScopeAttribute : MethodInterceptionAspect
{
public override void OnInvoke(MethodInterceptionArgs args)
{
//declare the transaction options
var transactionOptions = new TransactionOptions();
//set it to read uncommited
transactionOptions.IsolationLevel = IsolationLevel.ReadUncommitted;
//create the transaction scope, passing our options in
using (var transactionScope = new TransactionScope(TransactionScopeOption.Required, transactionOptions))
{
//declare our context
using (var scope = new TransactionScope())
{
args.Proceed();
scope.Complete();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后,只要你需要它,
[ReadUncommitedTransactionScope()]
public static SomeEntities[] GetSomeEntities()
{
using (var context = new MyEntityConnection())
{
//any reads we do here will also read uncomitted data
//...
//...
}
}
Run Code Online (Sandbox Code Playgroud)
能够使用拦截器添加"NOLOCK"也很不错,但是当连接到像Oracle这样的其他数据库系统时也无法工作.
随着 EF6 的引入,Microsoft 建议使用 BeginTransaction() 方法。
您可以在 EF6+ 和 EF Core 中使用 BeginTransaction 而不是 TransactionScope
using (var ctx = new ContractDbContext())
using (var transaction = ctx.Database.BeginTransaction(System.Data.IsolationLevel.ReadUncommitted))
{
//any reads we do here will also read uncommitted data
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
66467 次 |
| 最近记录: |