Entity Framework - каково значение текущего тайм-аута команды

Я использую Entity Framework 5 и хочу знать значение тайм-аута команды.

Чтобы сделать это, я передал объект dbContext объекту ObjectContext, и я получаю доступ к свойству CommandTimeout.

int ? currentCommandTimeout = ((IObjectContextAdapter)dbContext).ObjectContext.CommandTimeout;

Текущее значение этого свойства равно null, что означает, что текущий тайм-аут команды является значением по умолчанию для базового провайдера.

  • Кто является основным поставщиком?
  • Как я могу прочитать (через EF-код) текущее значение тайм-аута команды в этом случае?

MSDN ObjectContext CommandTimeout Ссылка на свойства

EDIT: Благодарим вас за объяснение того, как установить тайм-аут команды и найти значение тайм-аута команды по умолчанию в документации. Однако вопрос остается открытым. Как, если возможно, вы можете прочитать значение таймаута команды в случае по умолчанию через EF.

Ответ 1

Из MSDN,

  • Свойство CommandTimeout получает или устанавливает значение таймаута в секундах для всех операций контекста объекта.
  • Значение A null означает, что будет использоваться значение по умолчанию для базового провайдера.

Итак, если вы не устанавливаете его явно через код или не передаете его в строку соединения (в MySQL), это значение по умолчанию вашего провайдера.

Если вы хотите увидеть ненулевое значение для CommandTimeout, вам необходимо передать его в connectionString или установить его через код.

Кто является основным поставщиком?

Базовый поставщик - это тот, который вы передаете в своей строке соединения как providerName

<connectionStrings>
  <clear />
  <add name="Name" 
   providerName="System.Data.ProviderName" 
   connectionString="Valid Connection String;" />
</connectionStrings>

Здесь System.Data.ProviderName - ваш основной поставщик.

Если вы используете MySql или MS Sql, согласно MySql Documentation и MSDN,

  • Значение по умолчанию 30 secs.
  • Значение 0 указывает на неопределенное ожидание и его следует избегать.

    Примечание:

Тайм-аут команды по умолчанию можно изменить с помощью атрибута connectionstring Default Command Timeout в случае поставщиков баз данных MySQL.

Ответ 2

Если вы используете SQLServer, тогда время ожидания команды по умолчанию составляет 30 секунд.

Свойство SqlCommand.CommandTimeout

Ответ 3

  • Кто является основным провайдером?

Для подключения к любой базе данных удаленно и запуска запросов SQL вам нужен механизм или посредник (вы можете сказать), который понимает семантику связи различных действий, которые необходимо предпринять при запуске запроса, например. создание команды, соединение, уход за тайм-аутом соединения, повторение и т.д.

Все эти обязанности выполняются провайдерами для базы данных, к которой вы пытаетесь подключиться. Эти поставщики будут иметь разные реализации и классы w.r.t. среду (С#, Java, Python, Perl и т.д.), из которой вы подключаетесь. Таким образом, чтобы подключиться к базе данных MySQL, у вас будут разные поставщики для java,.net или мира программирования на пионе.

  1. Как я могу прочитать (через EF-код) текущее значение тайм-аута команды в этом случае?

Неа. Это невозможно. Если вы внимательно посмотрите на свойство dbContext.Database.CommandTimeout, оно имеет тип int?. Таким образом, логистика сохранения этого свойства как nullable int представляет только значение по умолчанию (как null). Entity Framework (EF) не раскрывает ничего, пока вы не установили явное значение в коде С#. Я проверил это против следующих баз данных

  • MySQL
  • SQL Server

В обоих случаях я вижу, что после создания объекта контекста DB свойство timeout команды установлено на null, что предполагает, что он использует значение по умолчанию, предоставляемое базовым провайдером.

Но да, если вы установили значение не равного null в свой код С# через свойство dbContext.Database.CommandTimeout, то вы можете, конечно, прочитать его снова, поскольку это свойство get-set в объекте команды. Он всегда будет показывать вам новое значение, которое явно указано в коде.

Если вы установите его на null, тогда EF снова начнет использовать тайм-аут по умолчанию для базового провайдера.

Использование классов поставщика вместо уровня EF. Если вы не используете слой ORM-структуры сущности и используете основные классы провайдера, тогда вы, безусловно, можете увидеть значение тайм-аута по умолчанию для самой инициализации, Например, когда я запустил указанный ниже код для базы данных MySQL с значением времени ожидания по умолчанию, которое уже установлено в самой строке соединения, вы увидите 40.

private static void TestingCommandTimeOutInMySql()
        {
            string connetionString = "Server=localhost;Database=sakila;Uid=root;Pwd=Passw0rd;default command timeout=40;";
            MySqlConnection con = new MySqlConnection(connetionString);
            try
            {
                cnn.Open();
                Console.WriteLine("Connection Open ! ");
                MySqlCommand cmd = new MySqlCommand("select * from actor", con);
                var timeoutValue = cmd.CommandTimeout; //shows 40
                con.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine("Can not open connection ! ");
            }
        }

Если вы не устанавливаете ничего в строке подключения, оно показывает значение по умолчанию 30 для MySQL. Здесь CommandTimeout - int, NOT int?. Таким образом, EF, безусловно, применяет некоторый интеллект, подвергая это свойство классам провайдеров, которые в конечном итоге подвергаются EF через dbContext.Database.CommandTimeout. EF - это всего лишь обертка над этими классами провайдеров с некоторым дополнительным интеллектом.

Немного о деталях касания соединений:

Для поставщика SQL Server: Форматы строк подключения Microsoft SQL Server не предоставляют никакого свойства, с помощью которого вы можете установить тайм-аут выполнения пользовательской команды. Поэтому установка значения во время инициализации поставщика SQL Server просто невозможна. Вы всегда можете изменить значение в коде С#, хотя после intantiation/initialization. Вы можете увидеть более подробную информацию здесь.

Для поставщика MySQL: В моих строковых форматах соединений SQL есть поддержка для установки тайм-аута команды по умолчанию явно. Здесь вы можете найти подробности здесь. Вы можете указать пользовательское значение тайм-аута команды по умолчанию в строке подключения MySQL, как это, -

default command timeout=200;

Ответ 4

Это должно работать

var ctx = new DbContext();
ctx.Database.CommandTimeout = 120;

Ответ 5

Вот как я это делаю.

ObjectContext objectContext = ((IObjectContextAdapter)dbContext).ObjectContext
int commandTimeout = objectContext.CommandTimeout 
    ?? objectContext.Connection.CreateCommand().CommandTimeout;