我有一个存储过程,它执行了相当多的连接。虽然查询运行得非常快,大约3秒。我只是不能弄清楚下面的错误每隔一段时间弹出一次。我将使用此查询的文档事件缓存一分钟,这样它就不会一遍又一遍地运行。我正在使用Entity Framework 5,并且我的存储过程正在使用CTE进行分页。有什么线索或见解吗?
System.Data.SqlClient.SqlException (0x80131904): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. ---> System.ComponentModel.Win32Exception (0x80004005): The wait operation timed out
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()
at System.Data.SqlClient.SqlDataReader.get_MetaData()
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.ExecuteReader()
at System.Data.Objects.ObjectContext.ExecuteStoreQueryInternal[TElement](String commandText, String entitySetName, MergeOption mergeOption, Object[] parameters)
at System.Data.Objects.ObjectContext.ExecuteStoreQuery[TElement](String commandText, Object[] parameters)
at System.Data.Entity.Internal.InternalContext.ExecuteSqlQuery[TElement](String sql, Object[] parameters)
at System.Data.Entity.Internal.InternalContext.ExecuteSqlQueryAsIEnumerable[TElement](String sql, Object[] parameters)
at System.Data.Entity.Internal.InternalContext.ExecuteSqlQuery(Type elementType, String sql, Object[] parameters)
at System.Data.Entity.Internal.InternalSqlNonSetQuery.GetEnumerator()
at System.Data.Entity.Internal.InternalSqlQuery`1.GetEnumerator()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Tournaments.Data.Repositories.Games.GamesRepository.GetGamesPaged(IGamesCriteria criteria)
public PagedResult<GameComplex> GetGamesPaged(IGamesCriteria criteria)
{
var results = DataContext.Database.SqlQuery<GameComplex>("EXEC [Schema].[Database] @Page, @PageSize, @SortOrder, @SortDirection, @EventId, @DivisionId, @DivisionTeamId, @Date, @SearchToken, @MemberId",
new SqlParameter("Page", criteria.Page),
new SqlParameter("PageSize", criteria.PageSize),
new SqlParameter("SortOrder", GetDataValue(criteria.SortOrder)),
new SqlParameter("SortDirection", GetDataValue(criteria.SortDirection)),
new SqlParameter("EventId", GetDataValue(criteria.EventId)),
new SqlParameter("DivisionTeamId", GetDataValue(criteria.DivisionTeamId)),
new SqlParameter("DivisionId", GetDataValue(criteria.DivisionId)),
new SqlParameter("Date", GetDataValue(criteria.Date)),
new SqlParameter("SearchToken", GetDataValue(criteria.SearchToken)),
new SqlParameter("MemberId", GetDataValue(criteria.MemberId))).ToList();
return new PagedResult<GameComplex>
{
Page = criteria.Page,
PageSize = criteria.PageSize,
Total = results.Any(q => q != null) ? results.FirstOrDefault().Total : 0,
Results = results
};
}
SQL Server存储过程参数签名
ALTER PROCEDURE [Schema].[Database]
@Page INT = 1,
@PageSize INT = 10,
@SortOrder NVARCHAR(100) = 'Id',
@SortDirection VARCHAR(4) = 'ASC',
@EventId INT = NULL,
@DivisionId INT = NULL,
@DivisionTeamId INT = NULL,
@Date DATETIME = NULL,
@SearchToken NVARCHAR(100) = NULL,
@MemberId INT = NULL
AS
您可能需要调整COMMAND超时时间
:
设置实体框架命令超时4.3
或
如何设置DbContext的CommandTimeout ?
编辑命令超时:http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.commandtimeout.aspx
连接超时:
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.connectiontimeout.aspx 编辑:另一个可能的问题是"参数嗅探"。
http://blogs.msdn.com/b/queryoptteam/archive/2006/03/31/565991.aspx那么尝试一种参数嗅探方法:
ALTER PROCEDURE [Schema].[Database]
@Page INT = 1,
@PageSize INT = 10,
@SortOrder NVARCHAR(100) = 'Id',
@SortDirection VARCHAR(4) = 'ASC',
@EventId INT = NULL,
@DivisionId INT = NULL,
@DivisionTeamId INT = NULL,
@Date DATETIME = NULL,
@SearchToken NVARCHAR(100) = NULL,
@MemberId INT = NULL
AS
Declare @PageCopyOf int
Select @PageCopyOf = @Page
Declare @PageSizeCopyOf int
Select @PageSizeCopyOf = @PageSize
Declare @SortOrderCopyOf NVARCHAR(100)
Select @SortOrderCopyOf = @SortOrder
Declare @SortDirectionCopyOf VARCHAR(4)
Select @SortDirectionCopyOf = @SortDirection
Declare @EventIdCopyOf int
Select @EventIdCopyOf = @EventId
Declare @DivisionIdCopyOf int
Select @DivisionIdCopyOf = @DivisionId
Declare @DivisionTeamIdCopyOf int
Select @DivisionTeamIdCopyOf = @DivisionTeamId
Declare @DateCopyOf DATETIME
Select @DateCopyOf = @Date
Declare @SearchTokenCopyOf NVARCHAR(100)
Select @SearchTokenCopyOf = @SearchToken
Declare @MemberIdCopyOf int
Select @MemberIdCopyOf = @MemberId
下面的所有内容都使用/消耗@XXXXXCopyOf变量,而不是原始变量(name)。
值得一试
只是猜测,但是查询只有在缓存时才运行得很快(3秒)。否则,它将花费更长的时间,并且超出服务器超时设置。因为System.Data.SqlClient正在引发异常,所以很可能默认的超时时间只有15秒。
MSDN: "默认为15秒"
或者,尝试SQLCommand对象的CommandTimeout属性,默认为30秒。
CommandTimeout