我的asp.net mvc web应用程序中有folloiwng方法,我使用Entity框架作为数据访问层: -
public IEnumerable<AaaUserContactInfo> getcontactinfo(long[] id)
{
var organizationsiteids = (from accountsitemapping in entities.AccountSiteMappings
where id.Any(accountid => accountsitemapping.ACCOUNTID == accountid)
select accountsitemapping.SITEID).ToList();
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)
var contactsinfos = from contactinfo in entities.AaaUserContactInfoes
join userdept in usersdepts on contactinfo.USER_ID equals userdept.USERID
select contactinfo;
return contactsinfos;
但如果记录数量巨大,那么我将得到以下错误: -
SQL语句的某些部分嵌套太深。重写了 查询或将其分解为较小的查询。描述:未处理 在执行当前Web请求期间发生异常。 请查看堆栈跟踪以获取有关错误的更多信息 它起源于代码。
异常详细信息:System.Data.SqlClient.SqlException:部分内容 你的SQL语句嵌套得太深了。重写查询或破解它 进入较小的查询。
来源错误:
执行期间生成了未处理的异常 当前的网络请求。有关的来源和位置的信息 可以使用下面的异常堆栈跟踪来识别异常。
堆栈追踪:
[SqlException(0x80131904):SQL语句的某些部分是嵌套的 太深了重写查询或将其分解为较小的查询。] System.Data.SqlClient.SqlConnection.OnError(SqlException异常, Boolean breakConnection,Action
1 wrapCloseInAction) +388
1完成,Int32超时,Task&amp;任务, Boolean asyncWrite)+577
System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) +688
System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) +4403
System.Data.SqlClient.SqlDataReader.TryConsumeMetaData() +82
System.Data.SqlClient.SqlDataReader.get_MetaData() +135
System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) +6665229
System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite) +6667096
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource
System.Data.SqlClient.SqlCommand.RunExecuteReader(的CommandBehavior cmdBehavior,RunBehavior runBehavior,Boolean returnStream,String 方法)+107
System.Data.SqlClient.SqlCommand.ExecuteReader(的CommandBehavior 行为,字符串方法)+288
System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(的CommandBehavior 行为)+180
System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand,CommandBehavior行为)+689
如果返回的记录数量很少,那么代码可以正常工作,那么问题可能是什么呢?
答案 0 :(得分:3)
根据评论中上面提到的重复问题的答案,尝试以下作为第一个查询的where子句,因为最有可能是那个给出所有麻烦的那个:
where id.Contains(accountsitemapping.ACCOUNTID)
答案 1 :(得分:1)
我很想删掉那里的所有联接并单独进行查找。
这样做可能会产生反效果,但如果你
var organizationsiteids = (from accountsitemapping in entities.AccountSiteMappings
where id.Any(accountid => accountsitemapping.ACCOUNTID == accountid)
select accountsitemapping.SITEID).ToList();
然后将其保留在内存中,循环遍历该集合并使用它从数据库中获取其余的详细信息,它将简化查询,并可能解决错误。
然而,作为对实际问题的回答,最有可能生成的SQL是在幕后生成SQL连接,这些连接必须有许多连接条件,或者是SQL服务器要处理的嵌套查询。
你可以做两件事来帮助解决这个问题。
1)如果您有权访问正在使用的SQL服务器,请使用SQL Server Profiler工具,并查看正在生成的SQL代码。或者2)(我不记得如何做到这一点)但是获得EF / L2S或者你用什么来将SQL输出到visual studio中的调试/输出窗口。
您可能想做的最后一件事。
下载LinqPad(http://www.linqpad.net/)并使用它在您的代码中重现查询,然后您可以坐在沙盒中使用Linq语句,以帮助您了解正在发生的事情
除非你能发布正在生成的SQL(选项1是首选方式),而且我现在正在网上登录,所以除此之外我不能提供更多的帮助: - )
答案 2 :(得分:0)
另一个解决方案是迭代记录获取另一个并聚合到最终列表。
这不是最快,不是美,而是会解决。