[英]Timeout exception running Linq Statement
This just started happening. 这才刚刚开始发生。 This statement was working for months, now I just keep getting the timeout error below.
这个声明已经工作了几个月,现在我只是继续得到下面的超时错误。 when I execute the same statement directly on the SSMS it comes back in a second.
当我直接在SSMS上执行相同的语句时,它会在一秒钟内返回。 the table has 44k records and is index on 5 columns state being one of them.
该表有44k记录,并且是5列状态的索引,其中一列是其中之一。
select distinct(state) from [ZipCodeDatabase]
I am running the following linq statement 我正在运行以下linq语句
states = ZipCodeRepository.Get(orderBy: z => z.OrderBy(o => o.State)).Select(z => z.State).Distinct().ToList();
When I run this linq statement I am continually getting a timeout error and have no idea y since it was working correctly before. 当我运行这个linq语句时,我不断收到超时错误并且不知道y因为它之前正常工作。
I included the Get()
function which is a generic repo function, but maybe I am missing something there, that is causing the delay. 我包含了
Get()
函数,它是一个通用的repo函数,但也许我在那里遗漏了一些东西,这导致了延迟。
Get Function: 获取功能:
public virtual IEnumerable<TEntity> Get(
Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
string includeProperties = "") //params Expression<Func<TEntity, object>>[] includes
{
IQueryable<TEntity> query = dbSet;
if (filter != null)
{
query = query.Where(filter);
}
foreach (var includeProperty in includeProperties.Split
(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProperty);
}
if (orderBy != null)
{
return orderBy(query).ToList();
}
else
{
return query.ToList();
}
}
The timeout error: 超时错误:
System.Data.SqlClient.SqlException (0x80131904): Timeout expired.
System.Data.SqlClient.SqlException(0x80131904):超时已过期。 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.TryCloseInternal(Boolean closeReader) at System.Data.SqlClient.SqlDataReader.Close() at System.Data.Common.DbDataReader.Dispose(Boolean disposing) at System.Data.Common.DbDataReader.Dispose() at System.Data.Common.Internal.Materialization.Shaper1.Finally() at System.Data.Common.Internal.Materialization.Shaper
---> System.ComponentModel.Win32Exception(0x80004005):在System.Data.SqlClient.SqlInternalConnection.OnError处的System.Data.SqlClient.SqlConnection.OnError(SqlException异常,Boolean breakConnection,Action
1 wrapCloseInAction) at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action
等待操作超时1 wrapCloseInAction) at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action
System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior,SqlCommand cmdHandler,SqlDataReader dataStream,System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj,Boolean callerHasConnectionLock,Boolean asyncClose)中的1 wrapCloseInAction) at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action
1 wrapCloseInAction) BulkCopySimpleResultSet bulkCopyHandler,TdsParserStateObject stateObj,Boolean&dataReady)at System.Data.SqlClient.SqlDataReader.TryCloseInternal(Boolean closeReader)at System.Data.SqlClient.SqlDataReader.Close()at System.Data.Common.DbDataReader.Dispose(Boolean disposing)at at System.Data.Common.Internal.Materialization.Shaper的System.Data.Common.DbDataReader.Dispose1.Finally() at System.Data.Common.Internal.Materialization.Shaper
1.Finally() at System.Data.Common.Internal.Materialization.Shaper
1.SimpleEnumerator.Dispose() at System.Collections.Generic.List1..ctor(IEnumerable
1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source) at ClientsToProfitsKendoUI.DAL.GenericRepository
1.Get(Expression1 filter, Func
2 orderBy, String includeProperties)1.Finally() at System.Data.Common.Internal.Materialization.Shaper
()在System.Collections.Generic.List1..ctor(IEnumerable
1 collection)System.Linq.Enumerable.ToList [TSource](IEnumerable1 source) at ClientsToProfitsKendoUI.DAL.GenericRepository
(表达式1 filter, Func
2 orderBy,String includeProperties)
Your get method always calls ToList
, which materializes the query at that point. 您的get方法始终调用
ToList
,该列表在此时实现查询。 Meaning that it will grab all 44k records from the database before doing any filtering. 这意味着它会在进行任何过滤之前从数据库中获取所有44k记录。
You're also doing the ordering by state before actually selecting any data, which is a useless exercise in ordering arbitrary data. 在实际选择任何数据之前,您还要按状态进行排序,这对于排序任意数据是一种无用的练习。
From your Get
method, remove the ToList
calls. 从
Get
方法中,删除ToList
调用。 And optimize your query by first selecting the State
, then calling Distinct
and then ordering. 并通过首先选择
State
,然后调用Distinct
然后排序来优化您的查询。 This allows the database to do its thing optimally. 这允许数据库以最佳方式完成任务。
If you need the list fully materialized, call ToList
at the very end. 如果您需要完全具体化的列表,请在最后调用
ToList
。 But until that, keep using the IQueryable
which your query returns. 但在此之前,请继续使用查询返回的
IQueryable
。 That way you can let Entity Framework offload as much as possible to the database. 这样,您可以让Entity Framework尽可能多地卸载到数据库中。
You're materializing every row in the database just to select distinct states. 您只是为了选择不同的状态而实现数据库中的每一行。 Let the database do the heavy lifting for you and simply return the states rather than materializing everything and then having .Net do it.
让数据库为您完成繁重的工作,只需返回状态而不是实现所有内容,然后让.Net执行此操作。
Add this to your ZipCodeRepository 将其添加到ZipCodeRepository中
public IEnumerable<string> GetStates()
{
return dbSet.OrderBy(e => e.State).Select(e => e.State).Distinct();
}
Note that what's causing the materialization (and a ton of overhead) is the ToList()
. 请注意,导致实现(以及大量开销)的原因是
ToList()
。
In general, keep the collection as an IQueryable until you're actually ready to to use the results. 通常,将集合保留为IQueryable,直到您真正准备好使用结果。 The moment you actually enumerate the collection EF will actually perform the query for you anyway.
实际枚举集合EF的那一刻,无论如何都会实际执行查询。
Alternatively, if you remove the ToList()
calls and change the return type of the Get
function to be IQueryable<TEntity>
that should also resolve the issue. 或者,如果删除
ToList()
调用并将Get
函数的返回类型更改为IQueryable<TEntity>
,它也应解决该问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.