开发中遇到的Too high level of nesting for select错误

项目使用了Entity Framework结合Mysql, 遇到了一个非常奇怪的性能问题,一个看起来非常简单的查询通过不了。

报出错误, “Too high level of nesting for select”。

整个查询非常简单,只是从表中取到属于一个集合中的id的数据, 比如从表中取到OfficeId 是1, 2,3,6的数据。

Expression<Func<office, bool>> filter = office => officeIds.Any(id => id == office.OfficeID);
var offices = _officeRepository.GetOffices(filter).ToList();

开始一直认为是Mysql的问题,是不是因为Id太多, mysql性能不好,后来发现问题出在EF的使用上。

实际的查询语句

后来调试,发现实际执行的sql语句是这样的,而不是我预想的in查询,而是翻译成了非常复杂的查询

SELECT
`Extent1`.`OfficeID`,
`Extent1`.`DoctorPhone`,
`Extent1`.`Name`,
`Extent1`.`RegionID`,
`Extent1`.`PriceTier2`,
`Extent1`.`PriceTier3`,
`Extent1`.`PracticeManagementSoftware`,
`Extent1`.`ServerHost`,
`Extent1`.`ServerLogin`,
FROM `office` AS `Extent1`
WHERE EXISTS(SELECT
1 AS `C1`
FROM (SELECT `UnionAll31`.`C1` FROM (SELECT `UnionAll30`.`C1` FROM (SELECT `UnionAll29`.`C1` FROM
(SELECT `UnionAll28`.`C1` FROM (SELECT `UnionAll27`.`C1` FROM (SELECT `UnionAll26`.`C1` FROM (SELECT `UnionAll25`.`C1` FROM
(SELECT `UnionAll24`.`C1` FROM (SELECT `UnionAll23`.`C1` FROM (SELECT `UnionAll22`.`C1` FROM (SELECT `UnionAll21`.`C1` FROM
(SELECT `UnionAll20`.`C1` FROM (SELECT `UnionAll19`.`C1` FROM (SELECT `UnionAll18`.`C1` FROM (SELECT `UnionAll17`.`C1` FROM
(SELECT `UnionAll16`.`C1` FROM (SELECT `UnionAll15`.`C1` FROM (SELECT `UnionAll14`.`C1` FROM (SELECT `UnionAll13`.`C1` FROM
(SELECT `UnionAll12`.`C1` FROM (SELECT `UnionAll11`.`C1` FROM (SELECT `UnionAll10`.`C1` FROM (SELECT `UnionAll9`.`C1` FROM
(SELECT `UnionAll8`.`C1` FROM (SELECT `UnionAll7`.`C1` FROM (SELECT `UnionAll6`.`C1` FROM (SELECT `UnionAll5`.`C1` FROM
(SELECT `UnionAll4`.`C1` FROM (SELECT `UnionAll3`.`C1` FROM (SELECT `UnionAll2`.`C1` FROM (SELECT `UnionAll1`.`C1` FROM
(SELECT 69 AS `C1` FROM (SELECT 1 AS `X`) AS `SingleRowTable1` UNION ALL SELECT 20 AS `C1` FROM (SELECT 1 AS `X`) AS `SingleRowTable2`) AS `UnionAll1`
UNION ALL SELECT 55 AS `C1` FROM (SELECT 1 AS `X`) AS `SingleRowTable3`) AS `UnionAll2` UNION ALL SELECT 67 AS `C1` FROM (SELECT 1 AS `X`) AS `SingleRowTable4`)
AS `UnionAll3` UNION ALL SELECT 9 AS `C1` FROM (SELECT 1 AS `X`) AS `SingleRowTable5`) AS `UnionAll4` UNION ALL SELECT 51 AS `C1` FROM
(SELECT 1 AS `X`) AS `SingleRowTable6`) AS `UnionAll5` UNION ALL SELECT 59 AS `C1` FROM (SELECT 1 AS `X`) AS `SingleRowTable7`) AS `UnionAll6` UNION ALL
SELECT 18 AS `C1` FROM (SELECT 1 AS `X`) AS `SingleRowTable8`) AS `UnionAll7` UNION ALL SELECT 19 AS `C1` FROM (SELECT 1 AS `X`) AS `SingleRowTable9`) AS `UnionAll8`
UNION ALL SELECT 8 AS `C1` FROM (SELECT 1 AS `X`) AS `SingleRowTable10`) AS `UnionAll9` UNION ALL SELECT 17 AS `C1` FROM (SELECT 1 AS `X`) AS `SingleRowTable11`) AS `UnionAll10`
UNION ALL SELECT 44 AS `C1` FROM (SELECT 1 AS `X`) AS `SingleRowTable12`) AS `UnionAll11` UNION ALL SELECT 4 AS `C1` FROM (SELECT 1 AS `X`) AS `SingleRowTable13`) AS `UnionAll12`
UNION ALL SELECT 3 AS `C1` FROM (SELECT 1 AS `X`) AS `SingleRowTable14`) AS `UnionAll13` UNION ALL SELECT 58 AS `C1` FROM (SELECT 1 AS `X`) AS `SingleRowTable15`) AS `UnionAll14`
UNION ALL SELECT 56 AS `C1` FROM (SELECT 1 AS `X`) AS `SingleRowTable16`) AS `UnionAll15` UNION ALL SELECT 57 AS `C1` FROM (SELECT 1 AS `X`) AS `SingleRowTable17`) AS `UnionAll16`
UNION ALL SELECT 52 AS `C1` FROM (SELECT 1 AS `X`) AS `SingleRowTable18`) AS `UnionAll17` UNION ALL SELECT 29 AS `C1` FROM (SELECT 1 AS `X`) AS `SingleRowTable19`) AS `UnionAll18`
UNION ALL SELECT 64 AS `C1` FROM (SELECT 1 AS `X`) AS `SingleRowTable20`) AS `UnionAll19` UNION ALL SELECT 48 AS `C1` FROM (SELECT 1 AS `X`) AS `SingleRowTable21`) AS `UnionAll20`
UNION ALL SELECT 15 AS `C1` FROM (SELECT 1 AS `X`) AS `SingleRowTable22`) AS `UnionAll21` UNION ALL SELECT 65 AS `C1` FROM (SELECT 1 AS `X`) AS `SingleRowTable23`) AS `UnionAll22`
UNION ALL SELECT 61 AS `C1` FROM (SELECT 1 AS `X`) AS `SingleRowTable24`) AS `UnionAll23` UNION ALL SELECT 50 AS `C1` FROM (SELECT 1 AS `X`) AS `SingleRowTable25`) AS `UnionAll24`
UNION ALL SELECT 62 AS `C1` FROM (SELECT 1 AS `X`) AS `SingleRowTable26`) AS `UnionAll25` UNION ALL SELECT 16 AS `C1` FROM (SELECT 1 AS `X`) AS `SingleRowTable27`) AS `UnionAll26`
UNION ALL SELECT 68 AS `C1` FROM (SELECT 1 AS `X`) AS `SingleRowTable28`) AS `UnionAll27` UNION ALL SELECT 49 AS `C1` FROM (SELECT 1 AS `X`) AS `SingleRowTable29`) AS `UnionAll28`
UNION ALL SELECT 12 AS `C1` FROM (SELECT 1 AS `X`) AS `SingleRowTable30`) AS `UnionAll29` UNION ALL SELECT 11 AS `C1` FROM (SELECT 1 AS `X`) AS `SingleRowTable31`) AS `UnionAll30`
UNION ALL SELECT 7 AS `C1` FROM (SELECT 1 AS `X`) AS `SingleRowTable32`) AS `UnionAll31` UNION ALL SELECT 5 AS `C1` FROM (SELECT 1 AS `X`) AS `SingleRowTable33`) AS `UnionAll32`
WHERE (`UnionAll32`.`C1`) = `Extent1`.`OfficeID`)

修改成IN查询

修改后的代码是,

Expression<Func<office, bool>> filter = office => officeIds.Contains(office.OfficeID);
var offices = _officeRepository.GetOffices(filter).ToList();

只是将Any方法,替换成了Contains, EF就正确的翻译成想要的IN查询了:

SELECT
`Extent1`.`OfficeID`,
`Extent1`.`DoctorPhone`,
`Extent1`.`Name`,
`Extent1`.`RegionID`,
`Extent1`.`IsActive`,
`Extent1`.`IsDeleted`,
`Extent1`.`InsuranceOnly`,
`Extent1`.`MinimumFlatRate`,
FROM `office` AS `Extent1`
WHERE `Extent1`.`OfficeID` IN ( 69,20,55,67,9,51,59,18,19,8,17,44,4,3,58,56,57,52,29,64,48,15,65,61,50,62,16,68,49,12,11,7,5 )

到这里,问题已经解决了,看来EF中的一些细节还需要自己不断地学习和实践。

Entity Framework做IN查询的更多相关文章

  1. 关于Entity Framework自动关联查询与自动关联更新导航属性对应的实体注意事项说明

    一.首先了解下Entity Framework 自动关联查询: Entity Framework 自动关联查询,有三种方法:Lazy Loading(延迟加载),Eager Loading(预先加载) ...

  2. Entity Framework入门教程: Entity Framework支持的查询方式

    Entity Framework支持的查询方式有三种 LINQ to Entities Entity SQL Native SQL [LINQ to Entities] LINQ(语言集成查询)是从V ...

  3. Entity Framework常用的查询方式

    Entity Framework支持的查询方式有三种 LINQ to Entities Entity SQL Native SQL [LINQ to Entities] LINQ(语言集成查询)是从V ...

  4. Entity Framework Core Like 查询揭秘

    在Entity Framework Core 2.0中增加一个很酷的功能:EF.Functions.Like(),最终解析为SQL中的Like语句,以便于在 LINQ 查询中直接调用. 不过Entit ...

  5. 如何使用 Entity Framework 构造动态查询表达式

    一般的程序员做上几年以后, 或多或少的都有些代码的积累, 我也不例外. 作为微软技术程序员, 自从Linq和EF出来之后, 就基本上爱不释手了, 且不说执行效率的问题, 单单就开发效率和代码的可移植性 ...

  6. Entity Framework中实现查询的几种方法

    在介绍几种方法前,献上一张图,希望图的作者不要追究我的盗图之过.本文的内容是我自学时的笔记,自学的内容来自网络.手打的代码,切不可直接复制过去用,会有好多错别字什么的. Entity SQL 类似于S ...

  7. Entity Framework 多对多查询的写法

    同学们,看下面的代码段就明白了: 一对多: public ICollection<ReportLookup> GetReportLookup(IEnumerable<Guid> ...

  8. C# Entity Framework查询小技巧 NoTracking

    在使用Entity Framework做查询的时候,如果只需要显示,而不用保存实体,那么可以用AsNoTracking()来获取数据. 这样可以提高查询的性能. 代码如下: var context = ...

  9. Entity Framework学习笔记(六)----使用Lambda查询Entity Framework(1)

    请注明转载地址:http://www.cnblogs.com/arhat 在前几章中,老魏一直使用Linq来查询Entity Framework.但是老魏感觉,如果使用Linq的话,那么Linq的返回 ...

随机推荐

  1. Love

    愿这段代码陪我走过此生,献给我最爱的榨菜. /** *@Description:<p>我爱榨菜</p> *@author 王旭 *@time 2016年4月25日 下午7:58 ...

  2. Direct2D开发:绘制网格

    转载请注明出处:http://www.cnblogs.com/Ray1024 一.引言 最近在使用Direct2D进行绘制工作中,需要实现使用Direct2D绘制网格的功能.在网上查了很多资料,终于实 ...

  3. UWP开发入门(十七)——判断设备类型及响应VirtualKey

    蜀黍我做的工作跟IM软件有关,UWP同时会跑在电脑和手机上.电脑和手机的使用习惯不尽一致,通常我倾向于根据窗口尺寸来进行布局的变化,但是特定的操作习惯是依赖于设备类型,而不是屏幕尺寸的,比如聊天窗口的 ...

  4. Gradle学习系列之九——自定义Task类型

    在本系列的上篇文章中,我们学习了多Project构建,在本篇文章中,我们将学到如何自定义Task类型. 请通过以下方式下载本系列文章的Github示例代码: git clone https://git ...

  5. 6/19 sprint3 看板和燃尽图的更新

  6. C# WinForm 技巧八:界面开发之“WeifenLuo.WinFormsUI.Docking+OutLookBar” 使用

    概述 转自 http://www.cnblogs.com/luomingui/archive/2013/09/19/3329763.html 最近几天一直在关注WinFrom方面的文章 有想着提炼一下 ...

  7. C#客户端Redis服务器的分布式缓存

    介绍 在这篇文章中,我想介绍我知道的一种最紧凑的安装和配置Redis服务器的方式.另外,我想简短地概述一下在.NET / C#客户端下Redis hash(哈希类型)和list(链表)的使用. 在这篇 ...

  8. 重新想象 Windows 8 Store Apps (70) - 其它: 文件压缩和解压缩, 与 Windows 商店相关的操作, app 与 web, 几个 Core 的应用, 页面的生命周期和程序的生命周期

    [源码下载] 重新想象 Windows 8 Store Apps (70) - 其它: 文件压缩和解压缩, 与 Windows 商店相关的操作, app 与 web, 几个 Core 的应用, 页面的 ...

  9. csharp:正则表达式采集网页数据

    https://msdn.microsoft.com/zh-cn/library/system.text.regularexpressions.regex(v=vs.110).aspx https:/ ...

  10. Unity中启动VS时出现"Visual Studio 2010 Shell 无效的许可证数据"的解决办法

    (感觉还是cnblog好一点,刚注册成功赶紧把baidu hi的一篇文章搬过来试试) 一直用着Visual Studio 2013给Unity写代码,安装了SQL Server 2014后,在Unit ...