ToList()的linq超时,由于使用DbContext

时间:2016-07-25 10:36:01

标签: c# .net entity-framework linq

在松散类型的LINQ查询上调用ToList()时,我遇到了linq超时的零星错误。我想通过从方法返回IQueryable并稍后枚举来优化它。但是,作为团队策略,我们使用带有DbContext的using语句;因此,一旦我退出using子句,我就无法枚举调用方法中的IQueryable

我的问题是:建议用using回避DbContext语句并让EF处理连接关闭和垃圾回收吗? 如果是,那么最好初始化context?何时何地处置它?

如果没有,还有什么其他方法来修复ToList()上的超时错误?

非常感谢。

我收到错误:

  

System.Data.Entity.Core.EntityCommandExecutionException:错误   执行命令定义时发生。看到内心   细节例外。 ---> System.Data.SqlClient.SqlException:   超时已过期。完成之前已经过了超时时间   操作或服务器没有响应。在   System.Data.SqlClient.SqlConnection.OnError(SqlException异常,   Boolean breakConnection)at   System.Data.SqlClient.SqlInternalConnection.OnError(SQLEXCEPTION   exception,Boolean breakConnection)at   System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()at   System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior,   SqlCommand cmdHandler,SqlDataReader dataStream,   BulkCopySimpleResultSet bulkCopyHandler,TdsParserStateObject   System.Data.SqlClient.SqlDataReader.ConsumeMetaData()中的stateObj)   在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)at   System.Data.SqlClient.SqlCommand.RunExecuteReader(的CommandBehavior   cmdBehavior,RunBehavior runBehavior,Boolean returnStream,String   方法,DbAsyncResult结果)at   System.Data.SqlClient.SqlCommand.RunExecuteReader(的CommandBehavior   cmdBehavior,RunBehavior runBehavior,Boolean returnStream,String   方法)at   System.Data.SqlClient.SqlCommand.ExecuteReader(的CommandBehavior   行为,String方法)at   System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(的CommandBehavior   行为)   System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
  在   System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.b__c(的DbCommand   t,DbCommandInterceptionContext 1 c) at System.Data.Entity.Infrastructure.Interception.InternalDispatcher 1.Dispatch [TTarget,TInterceptionContext,TResult](TTarget   target,Func 3 operation, TInterceptionContext interceptionContext, Action 3执行,Action`3执行)at   System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(的DbCommand   命令,DbCommandInterceptionContext interceptionContext)at   System.Data.Entity.Internal.InterceptableDbCommand.ExecuteDbDataReader(的CommandBehavior   行为)   System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
  在   System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand   entityCommand,CommandBehavior行为)

代码:

using (MyEntities context = new MyEntities())
{
myQuery =       from tableOne in context.TableOne
join tableTwo in context.TableTwo
on tableOne.My_OID equals tableTwo.My_OID
join tableThree in context.TableThree
on tableTwo.Location_OID equals     tableThree.Location_OID
join tableFour in context.TableFour
on tableTwo.JobPosting_OID equals tableFour.JobPosting_OID
join tableFive in context.TableFive
on tableFour.Client_OID equals tableFive.Client_OID
where 
tableOne.Editable_f == true && tableOne.Active_f == true
&& tableTwo.Active_f == true
&& tableFive.Active_f == true
&& tableThree.Active_f == true
&& tableFour.Active_f == true
&& tableFive.Employee_OID == givenUserID
&& tableThree.Employee_OID == givenUserID
&& tableFive.SchemaName.Equals("MySchema")
&& tableThree.SchemaName.Equals("MySchema")
orderby tableOne.MyName ascending
select new MyDTO
{
PropOne = tableOne.My_OID,
PropTwo = tableOne.MyName,
PropThree = tableOne.Create_By
};

return myQuery.ToList<MyDTO>();  

最后,我能以某种方式优化查询本身吗?我只是从TableOne返回值,所以我可以摆脱与其他表的连接并使用Any<>或SQL EXISTS的一些LINQ等效吗?

非常感谢任何帮助。非常感谢!

1 个答案:

答案 0 :(得分:1)

http://blog.jongallant.com/2012/10/do-i-have-to-call-dispose-on-dbcontext.html

这是关于处理EF dbcontext的好文章。简而言之,EF为您管理连接,您不必手动完成连接。但是,我建议在关闭DbContext之后尝试迭代IQueryable之前优化查询。使用Visual Studio Intellitrace或其他分析器捕获Sql Server语句,并查看查询有什么问题。实体框架中也有一些优化技巧,例如:急切加载 - Include()方法或AsNoTracking()方法。