Esta es la solución más correcta que encomtrarás brindar, pero estúdiala pausadamente y analiza si es compatible a tu proyecto.
Solución:
En primer lugar… NUNCA NUNCA debe usar NOLOCK para todas y cada una de las declaraciones SQL. Podría comprometer la integridad de sus datos.
Es como cualquier otra consulta, sugiere un mecanismo que solo debe usar cuando hace algo fuera de lo común.
No hay forma de decirle al proveedor de EF que represente la sugerencia de NoLock. Si realmente necesita leer datos no confirmados, tiene la siguiente opción.
-
Escriba su propio proveedor de EntityFramework.
-
Utilice un interceptor de comandos para modificar la declaración antes de que se ejecute. http://msdn.microsoft.com/en-us/data/dn469464.aspx
-
Use un TransactionScope con IsolationLevel.ReadUncommited.
Sé que dijiste que no quieres usar Transacciones, pero es la única forma lista para usar de leer datos no confirmados. Además, no produce muchos gastos generales ya que cada declaración en SQL Server se ejecuta “implícitamente” en una transacción.
using (new TransactionScope(
TransactionScopeOption.Required,
new TransactionOptions
IsolationLevel = IsolationLevel.ReadUncommitted
))
using (var db = new MyDbContext())
// query
EDITAR:
También es importante tener en cuenta que Microsoft ha dejado de usar NOLOCK para actualizaciones y eliminaciones (las selecciones permanecen intactas) a partir de SQL Server 2016 y se eliminará en una versión futura.
https://docs.microsoft.com/en-us/sql/database-engine/deprecated-database-engine-features-in-sql-server-2016?view=sql-server-2017
Puede usar una solución alternativa que no use ámbitos de transacción para cada consulta. Si ejecuta el código a continuación, ef utilizará el mismo nivel de aislamiento de transacciones para el mismo ID de proceso del servidor. Dado que el ID del proceso del servidor no cambia en la misma solicitud, solo es suficiente una llamada para cada solicitud. Esto también funciona en EF Core.
this.Database.ExecuteSqlCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;");
Estoy de acuerdo con lo que dice codeworx en el sentido de que Read Uncommitted puede ser peligroso. Si puedes vivir con lecturas sucias, hazlo.
Encontré una manera de hacer que esto funcione sin cambiar nada en las consultas actuales.
Necesita crear un DbCommandInterceptor como este:
public class IsolationLevelInterceptor : DbCommandInterceptor
private IsolationLevel _isolationLevel;
public IsolationLevelInterceptor(IsolationLevel level)
_isolationLevel = level;
//[ThreadStatic]
//private DbCommand _command;
public override void ReaderExecuting(DbCommand command, DbCommandInterceptionContext interceptionContext)
SetTransaction(command);
public override void ScalarExecuting(DbCommand command, DbCommandInterceptionContext
luego en el cctor (static constructor de su dbcontext) simplemente agregue el interceptor a la DbInfrastructure de las colecciones del marco de la entidad.
DbInterception.Add(new IsolationLevelInterceptor());
esto será para cada comando que EF envíe a la tienda, envuelve una transacción con ese nivel de aislamiento.
En mi caso funcionó bien, ya que escribimos datos a través de una API donde esos datos no se basan en las lecturas de la base de datos. (los datos pueden corromperse debido a las lecturas sucias) y funcionó bien.
Valoraciones y comentarios
Acuérdate de que te brindamos la opción de añadir un enjuiciamiento objetivo si diste con el resultado.