SQL语句的某些部分嵌套得太深。重写查询或将其分解为较小的查询

时间:2013-01-04 19:12:59

标签: c# asp.net-mvc entity-framework

我的控制器中有动作,它调用以下方法:

public IQueryable<AaaUserContactInfo> getcontactinfo(long[] id)
{
    var organizationsiteids = from accountsitemapping in entities.AccountSiteMappings
                            where id.Any(accountid => accountsitemapping.ACCOUNTID == accountid)
                            select accountsitemapping.SITEID;

    var usersdepts = from userdept in entities.UserDepartments
                    join deptdefinition in entities.DepartmentDefinitions on userdept.DEPTID equals deptdefinition.DEPTID
                    where organizationsiteids.Any(accountid => deptdefinition.SITEID == accountid)
                    select userdept;

    var contactsinfos = from userdept in usersdepts
                    join contactinfo in entities.AaaUserContactInfoes on userdept.USERID equals contactinfo.USER_ID
                    select contactinfo;

    return  contactsinfos;
}

但是当我运行应用程序并导航到action方法时,将在视图级别引发以下错误: -

System.Data.EntityCommandExecutionException was unhandled by user code
  HResult=-2146232004
  Message=An error occurred while executing the command definition. See the inner exception for details.
  Source=System.Data.Entity
  StackTrace:
       at System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)
       at System.Data.Objects.Internal.ObjectQueryExecutionPlan.Execute[TResultType](ObjectContext context, ObjectParameterCollection parameterValues)
       at System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
       at System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
       at System.Data.Entity.Internal.Linq.InternalQuery`1.GetEnumerator()
       at System.Data.Entity.Infrastructure.DbQuery`1.System.Collections.Generic.IEnumerable<TResult>.GetEnumerator()
       at System.Linq.Enumerable.Count[TSource](IEnumerable`1 source)
       at ASP._Page_Views_Home_CustomersDetails_cshtml.Execute() in c:\Users\Administrator\Desktop\new app DEMO2\MvcApplication4 - LATEST -\MvcApplication4\Views\Home\CustomersDetails.cshtml:line 6
       at System.Web.WebPages.WebPageBase.ExecutePageHierarchy()
       at System.Web.Mvc.WebViewPage.ExecutePageHierarchy()
       at System.Web.WebPages.StartPage.RunPage()
       at System.Web.WebPages.StartPage.ExecutePageHierarchy()
       at System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage)
       at System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance)
       at System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer)
       at System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context)
       at System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult)
       at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass1c.<InvokeActionResultWithFilters>b__19()
       at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation)
  InnerException: System.Data.SqlClient.SqlException
       HResult=-2146232060
       Message=Some part of your SQL statement is nested too deeply. Rewrite the query or break it up into smaller queries.
       Source=.Net SqlClient Data Provider
       ErrorCode=-2146232060
       Class=15
       LineNumber=105
       Number=191
       Procedure=""
       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)
            at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)
            at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
            at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
            at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
            at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
            at System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)
       InnerException:

那是什么导致了这个错误?

更新: - enter image description here

2 个答案:

答案 0 :(得分:18)

LINQ,对于它的大多数命令,都使用延迟执行。它会等待您在将查询发送到该数据库之前实际调用数据。在这里看起来所有这些查询都被推迟到稍后,当你试图从contactInfos中获取一些东西。

我会尝试执行它,比如在某处抛出一个.ToList()来尝试减少SQL中的嵌套。

编辑:因为根据评论,您似乎在第一个查询中收到错误,是否可以尝试说出where id.Contains(accountsitemapping.ACCOUNTID)

答案 1 :(得分:5)

为了将来参考,您可以使用以下命令记录生成的SQL:

var db = new DbContext();
db.Database.Log = Console.Write;

这将允许您确定哪个部分正在深层嵌套。从那里,您可能必须重新编写查询以在第二步中加载昂贵的计算。或者考虑将其写为存储过程。