update script migrations from framework force first existing enable code automatic linq entity-framework azure entity-framework-6 azure-sql-database

linq - migrations - update database script entity framework



Cómo usar SqlAzureExecutionStrategy y "Nolock" (1)

SqlAzureExecutionStrategy no admite transacciones iniciadas fuera de la acción para volver a intentarlo. Para evitar esta restricción, deberá suspender la estrategia, crear el alcance de la transacción y realizar el trabajo como una acción que pasa manualmente a la estrategia de ejecución para volver a intentarlo:

public AspnetUser GetAspnetUserByUserName(string userName) { new SuspendableSqlAzureExecutionStrategy().Execute(() => { using (var tx = new TransactionScope( TransactionScopeOption.Required, new TransactionOptions() { IsolationLevel = IsolationLevel.ReadUncommitted })) { return context.AspnetUsers.Where(x => x.UserName == userName).FirstOrDefault(); } }); }

Aquí estoy usando una alternativa a la estrategia suspendible de https://msdn.microsoft.com/en-us/data/dn307226 que suspenderá automáticamente cualquier invocación anidada:

using System.Data.Entity.Infrastructure; using System.Data.Entity.SqlServer; using System.Data.Entity.Utilities; using System.Runtime.Remoting.Messaging; using System.Threading; using System.Threading.Tasks; public class SuspendableSqlAzureExecutionStrategy : IDbExecutionStrategy { private readonly IDbExecutionStrategy _azureExecutionStrategy; public SuspendableSqlAzureExecutionStrategy() { _azureExecutionStrategy = new SqlAzureExecutionStrategy(); } private static bool Suspend { get { return (bool?)CallContext.LogicalGetData("SuspendExecutionStrategy") ?? false; } set { CallContext.LogicalSetData("SuspendExecutionStrategy", value); } } public bool RetriesOnFailure { get { return !Suspend; } } public virtual void Execute(Action operation) { if (!RetriesOnFailure) { operation(); return; } try { Suspend = true; _azureExecutionStrategy.Execute(operation); } finally { Suspend = false; } } public virtual TResult Execute<TResult>(Func<TResult> operation) { if (!RetriesOnFailure) { return operation(); } try { Suspend = true; return _azureExecutionStrategy.Execute(operation); } finally { Suspend = false; } } public virtual async Task ExecuteAsync(Func<Task> operation, CancellationToken cancellationToken) { if (!RetriesOnFailure) { await operation(); return; } try { Suspend = true; await _azureExecutionStrategy.ExecuteAsync(operation, cancellationToken); } finally { Suspend = false; } } public virtual async Task<TResult> ExecuteAsync<TResult>(Func<Task<TResult>> operation, CancellationToken cancellationToken) { if (!RetriesOnFailure) { return await operation(); } try { Suspend = true; return await _azureExecutionStrategy.ExecuteAsync(operation, cancellationToken); } finally { Suspend = false; } } } public class MyConfiguration : DbConfiguration { public MyConfiguration() { SetExecutionStrategy("System.Data.SqlClient", () => new SuspendableSqlAzureExecutionStrategy()); } }

Para manejar los tiempos de espera de SQL, intento usar SqlAzureExecutionStrategy ( https://msdn.microsoft.com/en-us/data/dn456835.aspx )

El problema al que me estoy enfrentando es que previene las "transacciones iniciadas por el usuario" que parecen ser la forma recomendada de implementar "con (nolock)" en EF ( http://www.hanselman.com/blog/GettingLINQToSQLAndLINQToEntitiesToUseNOLOCK.aspx , NOLOCK con Linq a SQL ).

código de ejemplo

public AspnetUser GetAspnetUserByUserName(string userName) { using (var tx = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions() { IsolationLevel = IsolationLevel.ReadUncommitted })) { return context.AspnetUsers.Where(x => x.UserName == userName).FirstOrDefault(); } }

lanza un error

La estrategia de ejecución configurada ''SqlAzureExecutionStrategy'' no admite transacciones iniciadas por el usuario. Consulte http://go.microsoft.com/fwlink/?LinkId=309381 para obtener información adicional.

He visto las respuestas que dicen que se apaga la estrategia SqlAzureExecutionStrategy por llamada, pero eso sería contrario al propósito de usarla, si todas mis lecturas ignoraran la estrategia. Es posible tener tanto "NoLock" como SqlAzureExecutionStrategy