No, pero puede iniciar una transacción y establecer el nivel de aislamiento para leer sin confirmar . Básicamente, esto hace lo mismo que NOLOCK, pero en lugar de hacerlo por tabla, lo hará para todo lo que esté dentro del alcance de la transacción.
Si eso suena como lo que quieres, así es como puedes hacerlo ...
//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();
}
Los métodos de extensión pueden facilitar esto
fuente
Si necesita algo en general, la mejor manera que encontramos de que es menos intrusivo que iniciar un alcance de transacciones cada vez, es simplemente establecer el nivel de aislamiento de transacción predeterminado en su conexión después de haber creado su contexto de objeto ejecutando este comando simple:
http://msdn.microsoft.com/en-us/library/aa259216(v=sql.80).aspx
Con esta técnica, pudimos crear un proveedor de EF simple que crea el contexto para nosotros y realmente ejecuta este comando cada vez para todo nuestro contexto para que siempre estemos en "lectura no comprometida" de forma predeterminada.
fuente
Transactions running at the READ UNCOMMITTED level do not issue shared locks
. Esto implica que debe estar ejecutándose dentro de una transacción para obtener el beneficio. (tomado de msdn.microsoft.com/en-gb/library/ms173763.aspx ). Su enfoque puede ser menos intrusivo, pero no logrará nada si no utiliza una transacción.SET TRANSACTION ISOLATION LEVEL...
comando afecta a una propiedad de nivel de conexión y, por lo tanto, afecta a todas las declaraciones SQL realizadas desde ese punto en adelante (para ESA conexión), a menos que se anule una sugerencia de consulta. Este comportamiento ha existido desde al menos SQL Server 2000, y probablemente antes.CREATE TABLE ##Test(Col1 INT); BEGIN TRAN; SELECT * FROM ##Test WITH (TABLOCK, XLOCK);
. Abrir otra consulta (# 2) y de ejecución:SELECT * FROM ##Test;
. SELECT no regresará ya que está siendo bloqueado por la transacción aún abierta en la pestaña # 1 que está usando un bloqueo exclusivo. Cancele SELECCIONAR en el n. ° 2. EjecutarSET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
una vez en la pestaña # 2. Ejecute nuevamente SELECT en la pestaña # 2 y volverá. Asegúrese de ejecutarROLLBACK
en la pestaña # 1.Aunque estuve absolutamente de acuerdo en que usar el nivel de aislamiento de transacciones no confirmadas de lectura es la mejor opción, pero en algún momento se obligó a usar la sugerencia de NOLOCK a pedido del gerente o cliente y no se aceptaron razones en contra de esto.
Con Entity Framework 6 puede implementar su propio DbCommandInterceptor de esta manera:
Con esta clase en su lugar, puede aplicarla al inicio de la aplicación:
Y apague condicionalmente la adición de
NOLOCK
pistas en las consultas para el hilo actual:fuente
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); }
Mejorar la respuesta aceptada del Doctor Jones y usar PostSharp ;
Primero " ReadUncommitedTransactionScopeAttribute "
Entonces, cuando lo necesites,
Ser capaz de agregar "NOLOCK" con un interceptor también es bueno, pero no funcionará cuando se conecte a otros sistemas de bases de datos como Oracle como tal.
fuente
Para evitar esto, creo una vista en la base de datos y aplico NOLOCK en la consulta de la vista. Luego trato la vista como una tabla dentro de EF.
fuente
Con la introducción de EF6, Microsoft recomienda usar el método BeginTransaction ().
Puede usar BeginTransaction en lugar de TransactionScope en EF6 + y EF Core
fuente
No, no realmente: Entity Framework es básicamente una capa bastante estricta sobre su base de datos real. Sus consultas están formuladas en ESQL (Entity SQL), que está dirigido en primer lugar a su modelo de entidad, y dado que EF admite múltiples backends de base de datos, realmente no puede enviar SQL "nativo" directamente a su backend.
La sugerencia de consulta NOLOCK es una cosa específica de SQL Server y no funcionará en ninguna de las otras bases de datos compatibles (a menos que también hayan implementado la misma sugerencia, lo cual dudo mucho).
Bagazo
fuente
Database.ExecuteSqlCommand()
oDbSet<T>.SqlQuery()
.(NOLOCK)
todos modos - mira Bad Habits para patear - poniendo NOLOCK en todas partes - NO SE RECOMIENDA usar esto en todas partes - ¡todo lo contrario!Una opción es usar un procedimiento almacenado (similar a la solución de vista propuesta por Ryan) y luego ejecutar el procedimiento almacenado desde EF. De esta manera, el procedimiento almacenado realiza la lectura sucia mientras EF simplemente canaliza los resultados.
fuente