在松散类型的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,DbCommandInterceptionContext1 c) at System.Data.Entity.Infrastructure.Interception.InternalDispatcher
1.Dispatch [TTarget,TInterceptionContext,TResult](TTarget target,Func3 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等效吗?
非常感谢任何帮助。非常感谢!
答案 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()方法。