本文将对LinqToEntity的方法进行分析,得出在实际开发过程中,什么时候应该使用什么方法。
实验工具
- Visual Studio2015/2017
- SqlServer2014
- SQL Server Profiler
实验步骤
- 根据不同情况编写Linq查询语句
- 运行Linq查询程序
- 使用SQL Server Profiler跟踪查询情况
- 分析查询结果数据
实验开始
1.GetAll()方法
示例用法
![](https://img.haomeiwen.com/i16345863/c0c0e76f770ac4cb.png)
产生SQL语句如下
![](https://img.haomeiwen.com/i16345863/5be4253da56582cd.png)
错误示例
![](https://img.haomeiwen.com/i16345863/4135c540a47b3b4d.png)
产生SQL如下
![](https://img.haomeiwen.com/i16345863/b5a8885d344d9370.png)
结论
- GetAll方法的只能在获取该表所有数据的场景下使用
- GetAll方法后面接的Where方法将不会生成SQL,也就是说Where是在把数据加载到内存中再进行筛选。
2.GetList()方法
示例用法
![](https://img.haomeiwen.com/i16345863/1c15d791a54dab05.png)
产生SQL如下
![](https://img.haomeiwen.com/i16345863/6a709e516bd39846.png)
错误示例
![](https://img.haomeiwen.com/i16345863/496a0d72d23aafb1.png)
产生SQL如下
![](https://img.haomeiwen.com/i16345863/4748f148b4cec160.png)
结论
- GetList()方法是在获取指定条件数据的场景下使用
- 错误示例指出在GetList后的分页方法在SQL上无体现,同上,也是加载到内存之后再进行分页操作
3.Get()方法
示例用法
![](https://img.haomeiwen.com/i16345863/309d35e9eb931207.png)
产生SQL如下
![](https://img.haomeiwen.com/i16345863/b636ac5f360bac1a.png)
结论
- Get()方法是在获取某条件的唯一数据场景下使用
4.GetById()方法
示例用法
![](https://img.haomeiwen.com/i16345863/50e8040629b75dee.png)
产生SQL如下
![](https://img.haomeiwen.com/i16345863/6674a021405af53d.png)
结论
- 在SQL中看出生成的SQL语句使用了参数化查询
- GetById方法的使用场景是使用该表的主键来获取数据
- 有一个疑问点就是为什么是Top(2),虽然主键是没关系
5.Add()方法
示例用法
![](https://img.haomeiwen.com/i16345863/c41b40316687b2f0.png)
产生SQL如下
![](https://img.haomeiwen.com/i16345863/700267e6f23b12de.png)
结论
- 可以看出Insert使用了参数化查询
- Insert之后还查询了一下主键返回给实体
6.BatchAdd()方法
示例用法
![](https://img.haomeiwen.com/i16345863/7bef7d9f35c682c9.png)
产生SQL如下
![](https://img.haomeiwen.com/i16345863/a55973b1cef74223.png)
结论
- 呃呃呃,可以看出是执行了两次SQL
- 所以说EF的性能问题,归根结底都是批量操作出的问题
- 该方法用户批量添加数据,但批量执行时间倒没优化多少,SQL方面没有减少,内存处理倒少了一点点
7.Update()方法
示例用法
![](https://img.haomeiwen.com/i16345863/46d3dc28c932789c.png)
产生SQL如下
![](https://img.haomeiwen.com/i16345863/9544e0a437abeb50.png)
结论
- Update方法需要查询出实体然后才能进行更新
8.Delete()方法
示例用法
![](https://img.haomeiwen.com/i16345863/5b2e7f98844b4f10.png)
产生SQL如下
![](https://img.haomeiwen.com/i16345863/5a495c4616173ee8.png)
结论
- Delete方法需要查询出实体然后才能进行删除
9.Exist()方法
示例用法
![](https://img.haomeiwen.com/i16345863/b8448134dced8359.png)
产生SQL如下
![](https://img.haomeiwen.com/i16345863/c869f07cd6a09147.png)
结论
- SQL语句大概意思是:存在数据返回1 不存在返回0
- 效率呢,也总比查出数据判断好
- Exist方法在判断数据是否存在的时候使用
10.Any()方法
示例用法
![](https://img.haomeiwen.com/i16345863/183a84a550db8e42.png)
产生SQL如下
![](https://img.haomeiwen.com/i16345863/03cf8be4269f8cea.png)
结论
- 跟Exist()一样哦,还不错
11.Except()方法
示例用法
![](https://img.haomeiwen.com/i16345863/72f46584a193b58c.png)
产生SQL如下
![](https://img.haomeiwen.com/i16345863/83c67cc86e741734.png)
结论
- Except方法是用来求两个数组的差集
- 在生成SQL的方面来看也没有多余操作,性能还OK
12.Union()方法
示例用法
![](https://img.haomeiwen.com/i16345863/5f35cc4c7931e24b.png)
产生SQL如下
![](https://img.haomeiwen.com/i16345863/a6bbbd241bf45198.png)
结论
- Union作用是连接不同集合,自动过滤相同项
- SQL语句也是完美的翻译了
13.Concat()方法
示例用法
![](https://img.haomeiwen.com/i16345863/704933cf70ee8a6b.png)
产生SQL如下
![](https://img.haomeiwen.com/i16345863/583f70c1572a3649.png)
结论
- Concat与Union相似,不同的是Concat没有过滤重复项
14.Intersect()方法
示例用法
![](https://img.haomeiwen.com/i16345863/17645282499564d6.png)
产生SQL如下
![](https://img.haomeiwen.com/i16345863/d5b7c95dae7736f2.png)
结论
- Intersect作用是获取两个集合的交集
- SQL语句还行
15.DistinctBy()方法
示例用法
![](https://img.haomeiwen.com/i16345863/211dd3a804bc701d.png)
产生SQL如下
![](https://img.haomeiwen.com/i16345863/36814dfd8833580d.png)
结论
- 从表面上来看,方法的作用是跟住某一字段来进行去重操作
- 从生成的SQL上来看,这是个巨大的坑
- 方法的原理是把所有数据加载到内存中进行筛选去重
16.Distinct()方法
示例用法
![](https://img.haomeiwen.com/i16345863/333354634cbf1375.png)
产生SQL如下
![](https://img.haomeiwen.com/i16345863/dc27b77d562f7e0e.png)
结论
- 从SQL上看,跟DistinctBy一个卵样,也是个性能坑
- 在实际开发过程中尽量不要使用这两个方法
17.Join
示例用法
![](https://img.haomeiwen.com/i16345863/6a9edf7957e7f5ea.png)
产生SQL如下
![](https://img.haomeiwen.com/i16345863/c983ea55c2f86ab7.png)
结论
- Join是SQL中的内连接,用于连表查询操作
18.GroupJoin
示例用法
![](https://img.haomeiwen.com/i16345863/6df55e1c9ba16850.png)
产生SQL如下
![](https://img.haomeiwen.com/i16345863/a4093987a2a6aa5e.png)
结论
- 从SQL看出GroupJoin产生的SQL语句是子查询操作
- 而且进一步分析GroupJoin里Y的操作越多,子查询的嵌套层数就越多。从而造成SQL性能极低。
- 开发中可代替左查询操作,但是性能确实会比左查询低
- 如需要左查询可以使用LinqToSQL中的DefaultIfEmpty实现
19.扩展方法-BatchUpdate()
示例用法
![](https://img.haomeiwen.com/i16345863/daa6337b5ac2cf98.png)
产生SQL如下
![](https://img.haomeiwen.com/i16345863/fc88440a2b3a2781.png)
结论
- 从SQL中看出这是一个直接更新子查询结果的SQL从而使批量更新性能提上去
- 方法需要引入EntityFramework.Extensions扩展类
20.扩展方法-BatchDelete()
示例用法
![](https://img.haomeiwen.com/i16345863/88edf40f386214e6.png)
产生SQL如下
![](https://img.haomeiwen.com/i16345863/92010384506f22ed.png)
结论
- SQL中看出BatchDelete方法是删除子查询结果来实现批量删除操作。
- 方法需要引入EntityFramework.Extensions扩展类
网友评论