Исключение Sql с .net 4 & EF
мы используем .net 4 MVC2 с EF и Sql Server 2005.
Для некоторых запросов, и это происходит редко, и только когда мы выполняем поиск, который реализуется с классами, сопоставленными с хранимыми процедурами, выполняющими полнотекстовый поиск, мы получаем
исключение:
[SqlException (0x80131904): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.]
System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) +2030802
System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) +5009584
System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() +234
System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) +2275
System.Data.SqlClient.SqlDataReader.ConsumeMetaData() +33
System.Data.SqlClient.SqlDataReader.get_MetaData() +86
System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) +311
System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) +987
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) +162
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) +32
System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) +141
System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior) +12
System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior) +10
System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior) +443
[EntityCommandExecutionException: An error occurred while executing the command definition. See the inner exception for details.]
System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior) +479
System.Data.Objects.ObjectContext.CreateFunctionObjectResult(EntityCommand entityCommand, EntitySet entitySet, EdmType edmType, MergeOption mergeOption) +182
System.Data.Objects.ObjectContext.ExecuteFunction(String functionName, MergeOption mergeOption, ObjectParameter[] parameters) +218
System.Data.Objects.ObjectContext.ExecuteFunction(String functionName, ObjectParameter[] parameters) +53
Если поиск повторяется после возникновения ошибки (с тем же или другим термином), он работает регулярно.
Любые хорошо оцененные предложения
Спасибо
- MB
THOUGHT 1: Исключение, похоже, происходит после подключения к серверу sql, и во время выполнения хранимой процедуры я прав? Если это так, то мне нужно будет продлить время выполнения запроса, а не таймаут соединения? Возможно ли это, где?
THOUGHT 2: Возможно, я ошибаюсь, и это может быть устаревшее соединение в пуле? В мире Java вы можете передать sql, который выполняется в соединении, прежде чем приложение получит его, чтобы убедиться, что соединение открыто и работает? Может ли это быть причиной этого. Я не смог найти такой вариант в http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.connectionstring.aspx
МЫСЛЬ 3: Я потерян:)
Ответы
Ответ 1
Вы можете попробовать установить свойство ObjectContext.CommandTimeout
:
Получает или задает значение таймаута в секундах для всех операций контекста объекта. Значение null указывает, что будет использоваться значение по умолчанию для базового провайдера.
Ответ 2
Да, попробуйте увеличить время ожидания соединения, которое находится в файле web.config:
<connectionStrings>
<add name="AdventureWorksEntities"
connectionString="metadata=.\AdventureWorks.csdl|.\AdventureWorks.ssdl|.\AdventureWorks.msl;
provider=System.Data.SqlClient;provider connection string='Data Source=localhost;
Initial Catalog=AdventureWorks;Integrated Security=True;**Connection Timeout=60;**
multipleactiveresultsets=true'" providerName="System.Data.EntityClient" />
</connectionStrings>
Кроме того, вы действительно пытались увидеть, сколько времени SPROC выполняет для выполнения при его выполнении вручную?
Ответ 3
Я использовал EF 4.3.1, SQL 2008 и имел ту же проблему с запросом EF linq, занимающим дольше, чем 30 секунд по умолчанию.
Итак, я установил "Время ожидания соединения = 120;" в строке соединения.
Затем переопределите конструктор DbContext и установите все таймауты команд для использования таймаута соединения из строки соединения;
public class FooContext : DbContext
{
public FooContext()
{
// Set all commands to use the connection timeout from the connection string
SetCommandTimeout(this.Database.Connection.ConnectionTimeout);
}
public void SetCommandTimeout(int timeout)
{
// Get the ObjectContext related to this DbContext
var objectContext = (this as IObjectContextAdapter).ObjectContext;
objectContext.CommandTimeout = this.Database.Connection.ConnectionTimeout;
}
}
Если вы хотите увеличить тайм-аут на некоторых запросах, удалите конструктор и установите, как требуется,
var db = new FooContext();
db.SetCommandTimeout(120);
db.Bars.ToList();
Ответ 4
Ответ Джеффа Огаты правильный, но он не решил проблему тайм-аута, которая у меня была, поэтому я подумал, что уточню, если кто-нибудь еще столкнется с этим. Если вы создаете команду для выполнения хранимой процедуры, для новой команды по умолчанию используется время ожидания 30 секунд независимо от времени ожидания, установленного в контексте. Вам нужно будет настроить этот тайм-аут отдельно. Вот пример:
_context.Database.CommandTimeout = 600; // This will not be used by cmd!
using (var cmd = _context.CreateCommandForStoredProc("StoredProcsName"))
{
cmd.CommandTimeout = 600;
await cmd.ExecuteScalarAsync();
}