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,
Тайм-аут команды по умолчанию можно изменить с помощью атрибута connectionstring Default Command Timeout
в случае поставщиков баз данных MySQL.
Ответ 2
Если вы используете SQLServer, тогда время ожидания команды по умолчанию составляет 30 секунд.
Свойство SqlCommand.CommandTimeout
Ответ 3
- Кто является основным провайдером?
Для подключения к любой базе данных удаленно и запуска запросов SQL вам нужен механизм или посредник (вы можете сказать), который понимает семантику связи различных действий, которые необходимо предпринять при запуске запроса, например. создание команды, соединение, уход за тайм-аутом соединения, повторение и т.д.
Все эти обязанности выполняются провайдерами для базы данных, к которой вы пытаетесь подключиться. Эти поставщики будут иметь разные реализации и классы w.r.t. среду (С#, Java, Python, Perl и т.д.), из которой вы подключаетесь. Таким образом, чтобы подключиться к базе данных MySQL, у вас будут разные поставщики для java,.net или мира программирования на пионе.
- Как я могу прочитать (через EF-код) текущее значение тайм-аута команды в этом случае?
Неа. Это невозможно. Если вы внимательно посмотрите на свойство dbContext.Database.CommandTimeout
, оно имеет тип int?
. Таким образом, логистика сохранения этого свойства как nullable int представляет только значение по умолчанию (как null). Entity Framework (EF) не раскрывает ничего, пока вы не установили явное значение в коде С#. Я проверил это против следующих баз данных
В обоих случаях я вижу, что после создания объекта контекста 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;