Não, mas você pode iniciar uma transação e definir o nível de isolamento para ler descomprometido . Isso basicamente faz o mesmo que o NOLOCK, mas, em vez de fazê-lo por tabela, o fará para tudo dentro do escopo da transação.
Se isso soa como o que você deseja, veja como você pode fazê-lo ...
//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();
}
Os métodos de extensão podem facilitar isso
fonte
Se você precisar de algo em geral, a melhor maneira que descobrimos ser menos invasiva do que realmente iniciar um escopo de transações a cada vez é simplesmente definir o nível de isolamento de transação padrão em sua conexão depois de criar o contexto do objeto executando este comando simples:
http://msdn.microsoft.com/en-us/library/aa259216(v=sql.80).aspx
Com essa técnica, fomos capazes de criar um provedor EF simples que cria o contexto para nós e, na verdade, executa esse comando todas as vezes para todo o nosso contexto, de modo que estamos sempre na "leitura não confirmada" por padrão.
fonte
Transactions running at the READ UNCOMMITTED level do not issue shared locks
. Isso implica que você deve estar executando dentro de uma transação para obter o benefício. (extraído de msdn.microsoft.com/en-gb/library/ms173763.aspx ). Sua abordagem pode ser menos intrusiva, mas não conseguirá nada se você não usar uma transação.SET TRANSACTION ISOLATION LEVEL...
comando afeta uma propriedade no nível da conexão e, portanto, afeta todas as instruções SQL feitas desse ponto em diante (para essa conexão), a menos que sejam substituídas por uma dica de consulta. Esse comportamento existe desde pelo menos o SQL Server 2000 e provavelmente antes.CREATE TABLE ##Test(Col1 INT); BEGIN TRAN; SELECT * FROM ##Test WITH (TABLOCK, XLOCK);
. Abra outra consulta (# 2) e execute:SELECT * FROM ##Test;
. O SELECT não retornará, pois está sendo bloqueado pela transação ainda aberta na guia nº 1, que está usando um bloqueio exclusivo. Cancele o SELECT no # 2. ExecuteSET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
uma vez na guia nº 2. Execute apenas o SELECT novamente na guia nº 2 e ele voltará. Certifique-se de executarROLLBACK
na guia nº 1.Embora eu tenha concordado absolutamente que usar o nível de isolamento de transação Read Uncommitted é a melhor opção, mas algum tempo você forçou a usar a dica NOLOCK por solicitação do gerente ou cliente e nenhuma razão contra isso foi aceita.
Com o Entity Framework 6, você pode implementar o próprio DbCommandInterceptor assim:
Com esta classe, você pode aplicá-la no início do aplicativo:
E desabilite condicionalmente a adição de
NOLOCK
dica nas consultas do encadeamento atual:fonte
public override void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext) { if (!SuppressNoLock) command.CommandText = $"SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;{Environment.NewLine}{command.CommandText}"; base.ReaderExecuting(command, interceptionContext); }
Aprimorar a resposta aceita pelo doutor Jones e usar o PostSharp ;
Primeiro " ReadUncommitedTransactionScopeAttribute "
Então, sempre que você precisar,
Ser capaz de adicionar "NOLOCK" a um interceptador também é bom, mas não funciona ao conectar-se a outros sistemas de banco de dados como o Oracle.
fonte
Para contornar isso, crio uma visualização no banco de dados e aplico NOLOCK na consulta da visualização. Trato então a visualização como uma tabela na EF.
fonte
Com a introdução do EF6, a Microsoft recomenda o uso do método BeginTransaction ().
Você pode usar BeginTransaction em vez de TransactionScope no EF6 + e EF Core
fonte
Não, na verdade - o Entity Framework é basicamente uma camada bastante rígida acima do banco de dados real. Suas consultas são formuladas no ESQL - SQL de entidade - que é primeiramente direcionado ao seu modelo de entidade e, como o EF suporta vários back-ends de banco de dados, você não pode realmente enviar SQL "nativo" diretamente para seu back-end.
A dica de consulta NOLOCK é uma coisa específica do SQL Server e não funcionará em nenhum dos outros bancos de dados suportados (a menos que eles também tenham implementado a mesma dica - o que duvido muito).
Marc
fonte
Database.ExecuteSqlCommand()
ouDbSet<T>.SqlQuery()
.(NOLOCK)
mesmo assim - veja Bad Habits to kick - colocando NOLOCK em todos os lugares - NÃO É RECOMENDADO usar isso em todos os lugares - muito pelo contrário!Uma opção é usar um procedimento armazenado (semelhante à solução de visualização proposta por Ryan) e, em seguida, executar o procedimento armazenado no EF. Dessa forma, o procedimento armazenado executa a leitura suja enquanto o EF apenas canaliza os resultados.
fonte