Вызов SetExecutionStrategy более одного раза - PullRequest
0 голосов
/ 16 апреля 2019

Я пытаюсь реализовать конфигурацию структуры объекта, которая имеет дело с взаимоблокировками и повторяет их.У меня уже есть стратегия выполнения по умолчанию, установленная в конструкторе MyConfiguration.У меня вопрос, могу ли я звонить один за другим, или они переопределят друг друга?Я не уверен на 100% в этом, поэтому любая информация будет принята с благодарностью.

Если я использую оба в своем конструкторе MyConfiguration, они будут переопределять друг друга или они фактически зарегистрируют оба, и поэтому оба будут работать?

Вот код:

public class MyConfiguration : DbConfiguration
{
    public MyConfiguration()
    {
        // Trims all strings coming from entity framework
        AddInterceptor(new StringTrimmerInterceptor());

        SetExecutionStrategy("System.Data.SqlClient", () => SuspendExecutionStrategy
          ? (IDbExecutionStrategy)new DefaultExecutionStrategy()
          : new SqlAzureExecutionStrategy());

        SetExecutionStrategy("System.Data.SqlClient", () => new MyCustomExecutionStrategy(5, TimeSpan.FromSeconds(10)));
    }

    public static bool SuspendExecutionStrategy
    {
        get
        {
            return (bool?)CallContext.LogicalGetData("SuspendExecutionStrategy") ?? false;
        }
        set
        {
            CallContext.LogicalSetData("SuspendExecutionStrategy", value);
        }
    }
}

public class StringTrimmerInterceptor : IDbCommandTreeInterceptor
{
    public void TreeCreated(DbCommandTreeInterceptionContext interceptionContext)
    {
        if (interceptionContext.OriginalResult.DataSpace == DataSpace.SSpace)
        {
            var queryCommand = interceptionContext.Result as DbQueryCommandTree;
            if (queryCommand != null)
            {
                var newQuery = queryCommand.Query.Accept(new StringTrimmerQueryVisitor());
                interceptionContext.Result = new DbQueryCommandTree(
                    queryCommand.MetadataWorkspace,
                    queryCommand.DataSpace,
                    newQuery);
            }
        }
    }

    private class StringTrimmerQueryVisitor : DefaultExpressionVisitor
    {
        private static readonly string[] _typesToTrim = { "nvarchar", "varchar", "char", "nchar" };

        public override DbExpression Visit(DbNewInstanceExpression expression)
        {
            var arguments = expression.Arguments.Select(a =>
            {
                var propertyArg = a as DbPropertyExpression;
                if (propertyArg != null && _typesToTrim.Contains(propertyArg.Property.TypeUsage.EdmType.Name))
                {
                    return EdmFunctions.Trim(a);
                }

                return a;
            });
            return DbExpressionBuilder.New(expression.ResultType, arguments);
        }
    }
}

public static class SqlRetryErrorCodes
{
    public const int TimeoutExpired = -2;
    public const int Deadlock = 1205;
    public const int CouldNotOpenConnection = 53;
    public const int TransportFail = 121;
}

public class MyCustomExecutionStrategy : DbExecutionStrategy
{
    public MyCustomExecutionStrategy(int maxRetryCount, TimeSpan maxDelay) : base(maxRetryCount, maxDelay) { }

    private readonly List<int> _errorCodesToRetry = new List<int>
        {
            SqlRetryErrorCodes.Deadlock,
            SqlRetryErrorCodes.TimeoutExpired,
            SqlRetryErrorCodes.CouldNotOpenConnection,
            SqlRetryErrorCodes.TransportFail
        };

    protected override bool ShouldRetryOn(Exception exception)
    {
        var sqlException = exception as SqlException;
        if (sqlException != null)
        {
            foreach (SqlError err in sqlException.Errors)
            {
                // Enumerate through all errors found in the exception.
                if (_errorCodesToRetry.Contains(err.Number))
                {
                    return true;
                }
            }
        }
        return false;
    }
}

1 Ответ

0 голосов
/ 16 апреля 2019

Глядя на это сообщение от члена команды .NET, он должен переопределять стратегию каждый раз, когда вы ее называете.Ссылка показывает, что это можно изменить даже во время выполнения (при каждом вызове ctor).В разделе использования он заявляет:

Теперь мы можем использовать флаг, чтобы отключить логику повторения для определенных операций.

Итак, мой (бездоказательный) ответ: Вы можете позвонитьэто более одного раза, и всегда будет настроена стратегия последнего набора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...