【问题标题】:linq timeout at ToList(), unable to use AsQueryable because of using DbContextToList() 的 linq 超时,由于使用 DbContext,无法使用 AsQueryable
【发布时间】:2016-07-25 10:36:00
【问题描述】:

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

我的问题是:是否建议使用 DbContext 避开 using 语句,让 EF 处理连接关闭和垃圾回收?
如果是,最好在哪里初始化context?何时何地处置?

如果没有,还有什么方法可以解决ToList() 的超时错误?

非常感谢。

我得到的错误:

System.Data.Entity.Core.EntityCommandExecutionException:错误 执行命令定义时发生。见内 细节例外。 ---> System.Data.SqlClient.SqlException: 超时已过。在完成之前超时时间已过 操作或服务器没有响应。在 System.Data.SqlClient.SqlConnection.OnError(SqlException 异常, 布尔中断连接)在 System.Data.SqlClient.SqlInternalConnection.OnError(SqlException 异常,布尔型 breakConnection) 在 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() 在 System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler、SqlDataReader 数据流、 BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) 在 System.Data.SqlClient.SqlDataReader.ConsumeMetaData() 在 System.Data.SqlClient.SqlDataReader.get_MetaData() 在 System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior,字符串 resetOptionsString) 在 System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior、RunBehavior runBehavior、布尔 returnStream、布尔 异步)在 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior、RunBehavior、runBehavior、布尔返回流、字符串 方法,DbAsyncResult 结果)在 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior、RunBehavior、runBehavior、布尔返回流、字符串 方法)在 System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior 行为,字符串方法)在 System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior 行为)在 System.Data.Common.DbCommand.ExecuteReader(CommandBehavior 行为)
在 System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.b__c(DbCommand t, DbCommandInterceptionContext1 c) at System.Data.Entity.Infrastructure.Interception.InternalDispatcher1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget 目标,Func3 operation, TInterceptionContext interceptionContext, Action3 执行,Action`3 执行)在 System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand 命令,DbCommandInterceptionContext 拦截上下文)在 System.Data.Entity.Internal.InterceptableDbCommand.ExecuteDbDataReader(CommandBehavior 行为)在 System.Data.Common.DbCommand.ExecuteReader(CommandBehavior 行为)
在 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&lt;&gt; 或 SQL EXISTS 的一些 LINQ 等效项吗?

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

【问题讨论】:

  • 稍后执行查询不会有任何区别。它只会推迟您获得超时的那一刻。对于优化,我们需要查看类及其导航属性。通常情况下,您不必join

标签: c# .net entity-framework linq


【解决方案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 语句并查看您的查询有什么问题。 Entity Framework 中也有一些优化技巧,例如急切加载 - Include() 方法或 AsNoTracking() 方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-21
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多