3

我在我的 asp.net mvc Web 应用程序中有以下方法,并且我使用实体框架作为数据访问层:-

        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 语句的某些部分嵌套得太深。重写查询或将其分解为更小的查询。

源错误:

在执行当前 Web 请求期间生成了未处理的异常。可以使用下面的异常堆栈跟踪来识别有关异常起源和位置的信息。

堆栈跟踪:

[SqlException (0x80131904): 你的 SQL 语句的某些部分嵌套太深。重写查询或将其分解为更小的查询。]
System.Data.SqlClient.SqlConnection.OnError(SqlException 异常,布尔 breakConnection,Action 1 完成,Int32 超时,Task& 任务,布尔 asyncWrite)+577 System.Data.SqlClient.SqlCommand .RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String 方法) +107 System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior 行为, String 方法) +288 System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior 行为) +1801 wrapCloseInAction) +388
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.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand,CommandBehavior 行为)+689

虽然如果返回的记录数很少,那么代码可以正常工作,那么可能是什么问题?

4

3 回答 3

3

根据评论中上述重复问题的答案,尝试以下作为第一个查询的 where 子句,因为这很可能是所有麻烦的问题:

where id.Contains(accountsitemapping.ACCOUNTID)

于 2013-01-06T18:17:38.230 回答
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 是首选方式),否则我无法提供更多帮助,而且我现在要在晚上登出互联网 :-)

于 2013-01-05T20:09:26.410 回答
0

另一种解决方案是遍历记录以获取另一个记录并聚合到最终列表。

它不是最快的,不是美丽的,而是会解决的。

于 2014-08-12T14:00:42.563 回答