Исключение 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();
}