首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >.NET SqlClient -超时过期

.NET SqlClient -超时过期
EN

Stack Overflow用户
提问于 2021-07-06 09:05:24
回答 1查看 386关注 0票数 1

目前,我正在.net核心的数据库上构建一个查询。其中一个查询有许多不同的过滤器,如下所示:

代码语言:javascript
复制
IQueryable<OperatingInstructionDTO> newQuery = this.Database.Set<OperatingInstructionDTO>()
                .Include(x => x.CurrentState)
                .Include(x => x.Plant)
                .Include(x => x.Department)
                .Include(x => x.Creator)
                .Where(x => x.Type != null && x.Type.Equals(type) && x.Department.Id == user.Department.Id);

            
            if (filter.InstructionTitle != null)
                newQuery = newQuery.Where(x => x.Title.Contains(filter.InstructionTitle));

            if (filter.SelectedStates != null)
                newQuery = newQuery.Where(x => filter.SelectedStates.Contains(x.CurrentState.Description));

            if (filter.SelectedEditors != null && filter.SelectedEditors.Count == 1)
            {
                if (filter.SelectedEditors[0].Equals("Eigene"))
                    newQuery = newQuery.Where(x => x.Creator.Email.Equals(user.Email));
                else
                    newQuery = newQuery.Where(x => !x.Creator.Email.Equals(user.Email));
            }

            if (filter.OverallTextFilter != null)
                newQuery = newQuery.Where(x =>x.Content!=null && x.Content.Contains(filter.OverallTextFilter));

            newQuery = newQuery.OrderByDescending(x => x.CreationTimestamp).ThenBy(x => x.Title).Take(filter.SelectedNumberOfResults);

            return newQuery.Select(x => new OperatingInstructionDTO
            {
                CreationTimestamp = x.CreationTimestamp,
                CurrentState = x.CurrentState,
                Department = x.Department,
                ParentOperatingInstruction = new OperatingInstructionDTO
                {

                },
                Plant = x.Plant,
                Title = x.Title,
                Id = x.Id,
                Creator = x.Creator,
                Type = x.Type
            }).ToList();

如果设置过滤器OverallTextFilter,则执行非常慢。我知道这一点,但是这个特性是客户所需要的。由于选择太慢,所以我得到以下错误消息:

代码语言:javascript
复制
System.Data.SqlClient.SqlException
  HResult=0x80131904
  Message=Timeout expired.  The timeout period elapsed prior to completion of the operation or the server is not responding.
  Source=Core .Net SqlClient Data Provider
  StackTrace:
   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, SqlDataReader ds)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior)
   at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at System.Data.Common.DbCommand.ExecuteReader()
   at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.Execute(IRelationalConnection connection, DbCommandMethod executeMethod, IReadOnlyDictionary`2 parameterValues)
   at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.ExecuteReader(IRelationalConnection connection, IReadOnlyDictionary`2 parameterValues)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.Enumerator.BufferlessMoveNext(DbContext _, Boolean buffer)
   at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.Enumerator.MoveNext()
   at System.Linq.Enumerable.SelectEnumerableIterator`2.MoveNext()
   at Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider.<_TrackEntities>d__17`2.MoveNext()
   at Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.MoveNext()
   at System.Collections.Generic.List`1.AddEnumerable(IEnumerable`1 enumerable)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at ModulareArbeitsanweisung.Database.Wrapper.InstructionManager.ReadOperationInstructionsWithFilter(UserDTO user, String type, InstructionFilter filter) in C:\Users\adlerlu\Desktop\CUE_GIT_REPO\SWP-Core-Backendservices\Modulare Arbeitsanweisung\ModulareArbeitsanweisung\ModulareArbeitsanweisung\Database\Wrapper\InstructionManager.cs:line 119
   at ModulareArbeitsanweisung.Controllers.InstructionController.List(InstructionFilter filter) in C:\Users\adlerlu\Desktop\CUE_GIT_REPO\SWP-Core-Backendservices\Modulare Arbeitsanweisung\ModulareArbeitsanweisung\ModulareArbeitsanweisung\Controllers\InstructionController.cs:line 64
   at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters)
   at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.SyncActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeActionMethodAsync>d__12.MoveNext()

Inner Exception 1:
Win32Exception: Der Wartevorgang wurde abgebrochen

我怎么才能解决这个问题?

EN

回答 1

Stack Overflow用户

发布于 2021-07-07 22:42:35

我强烈提醒您的客户不要进行这种类型的搜索。即使您延长了超时,您也为用户打开了一扇门,让用户意外地或有意地用昂贵的查询使您的系统瘫痪。用户是变化无常的野兽。当某事花费太长时间时,他们倾向于刷新浏览器,反复尝试相同的查询或调整查询,直到其正常工作,或者打开新的选项卡来触发查询。

对于文本搜索,只要有可能,您应该只支持BeginsWith类型搜索,作为可选的最后手段,可能会提供一个Contains。(也就是说,要么选择“开始于”(默认)vs.v。“包含”或“全文搜索”复选框,以向/w发送搜索请求)

当涉及到文本搜索时,您还应该考虑执行最小搜索期限(客户端和服务器端),以及服务器端对结果的分页。没有什么可以阻止用户进行搜索“其中的注释,如'%a%'”和潜在的性能和内存使用的后果。您可能期望用户搜索可能返回合理数量行的内容,但随着系统成熟,总数据大小可能会大幅度增长,这将为具有大量结果集的web服务器/数据库重载打开大门。

在企业系统中,这种类型的搜索是必需的,而其他方面的事情,比如潜在的昂贵的、广泛的报告,理想情况下您应该有一个复制的报告数据库实例。对于昂贵的搜索,运行这些搜索可以从报表副本检索摘要数据,而不是读/写数据库实例。(如果报告复制接近实时),这将保持行锁定之类的内容,以避免对记录的日常操作产生影响的脏读取。昂贵的搜索和报告也应该通过排队机制或类似机制进行代理,以避免一次处理太多昂贵的请求。这可以通过客户机的轮询循环或回调机制(如SignalR )来实现。

也就是说。

SearchID.

  • Server

  • 客户端代码发送搜索请求数据

  • Server,将搜索请求数据排队到一个工作池,以获取先到先得的服务,并将SearchQueued响应与SearchID一起返回给客户端。

  • 客户端等待n秒钟,使用

  • 服务器发送返回搜索结果,搜索查询/进度响应或SearchNotFound.

  • Client等待更多秒,并使用SearchID重复请求。

这在理想情况下包括取消令牌的实现,如果用户希望中止搜索以尝试其他内容,或者如果没有启动则离开页面来排列请求,或者告诉处理工作人员中止查询。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68267577

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档